外观模式(Facade)-6
也叫门面模式,过程模式。
外观模式为子系统中的一组接口提供一致的界面,此模式定义一个高层接口,使得子系统更容易使用。
需求分析
一个家庭影院使用过程:
放下屏幕
开爆米花
开DVD
...
播放DVD
暂停DVD
...
收起屏幕
收起爆米花
关DVD
使用外观模式,提供高层接口,简化家庭影院操作。
类图关系:

代码
Client
public class Client {
public static void main(String[] args) {
HomeTheatreFacade homeTheatreFacade = new HomeTheatreFacade();
System.out.println("--ready--");
homeTheatreFacade.read();
System.out.println("--play--");
homeTheatreFacade.play();
System.out.println("--pause--");
homeTheatreFacade.pause();
System.out.println("--end--");
homeTheatreFacade.end();
}
}
HomeTheatreFacade
public class HomeTheatreFacade {
// 子系统
private DVDPlayer dvdPlayer;
private Popcorn popcorn;
private Screen screen;
// 初始化子系统
public HomeTheatreFacade() {
// 结合单例模式
this.dvdPlayer = DVDPlayer.getInstance();
this.popcorn = Popcorn.getInstance();
this.screen = Screen.getInstance();
}
// 四个操作步骤
public void read(){
screen.down();
popcorn.open();
dvdPlayer.on();
}
public void play(){
dvdPlayer.play();
}
public void pause(){
dvdPlayer.pause();
}
public void end(){
dvdPlayer.off();
popcorn.close();
screen.up();
}
}
DVDPlayer
public class DVDPlayer {
// 单例模式
private DVDPlayer() {
}
private static DVDPlayer instance = new DVDPlayer();
public static DVDPlayer getInstance() {
return instance;
}
public void on(){
System.out.println("开DVD");
}
public void play(){
System.out.println("播放DVD");
}
public void pause(){
System.out.println("暂停DVD");
}
public void off(){
System.out.println("关闭DVD");
}
}
Popcorn
public class Popcorn {
// 单例模式
private Popcorn() {
}
private static Popcorn instance = new Popcorn();
public static Popcorn getInstance() {
return instance;
}
public void open(){
System.out.println("开爆米花");
}
public void close(){
System.out.println("收起爆米花");
}
}
Screen
public class Screen {
// 单例模式
private Screen() {
}
private static Screen instance = new Screen();
public static Screen getInstance() {
return instance;
}
public void down(){
System.out.println("放下屏幕");
}
public void up(){
System.out.println("收起屏幕");
}
}
举例
slf4j就是门面,它对多种日志框架进行兼容
slf4j-log4j12就是适配器,它适配log4j这种日志
统一接口调用
Logger logger = LoggerFactory.getLogger(HelloServlet.class);
装饰器模式(Decorator )-7
装饰器模式:动态将新功能附加到对象上。在对象扩展方面,比继承更有弹性,装饰者模式也体现了开闭原则(ocp)
问题引入:咖啡+调料问题。增加单品时,由于搭配种类很多,类的数量会暴增,出现类爆炸。考虑使用装饰者模式。
案例:咖啡调料
Component主体:Drink
ConcreteComponent:各单品咖啡
Decorator:各调料

CoffeeBar
/**
* 咖啡点单
*/
public class CoffeeBar {
public static void main(String[] args) {
// 1、一杯美式
Drink order = new LongBlack();
System.out.println("当前组合价格:"+ order.cost());
// 2、加一份牛奶
order = new Milk(order);
System.out.println("当前组合价格:"+ order.cost());
// 3、加两份巧克力
order = new Chocolate(order);
System.out.println("当前组合价格:"+ order.cost());
order = new Chocolate(order);
System.out.println("当前组合价格:"+ order.cost());
}
}
Drink
/**
* 饮品抽象类
*/
@Data
public abstract class Drink {
private float price = 0.0f;
private String description;
/**
* 计算费用
*/
public abstract float cost();
}
Coffee
/**
* 被装饰者:咖啡类
*/
public class Coffee extends Drink {
@Override
public float cost() {
// 实现Coffee计算逻辑,如基础价格...
return super.getPrice();
}
}
Decorator
/**
* 装饰器:加调料
*/
public class Decorator extends Drink{
// 被装饰对象:饮料
private Drink obj;
public Decorator(Drink obj) {
this.obj = obj;
}
@Override
public float cost() {
// getPrice : 调料的价格
return super.getPrice() + obj.cost();
}
}
DeCaf
public class DeCaf extends Coffee {
public DeCaf(){
setDescription("无因咖啡");
setPrice(1.0f);
}
}
LongBlack
public class LongBlack extends Coffee{
public LongBlack(){
setDescription("美式咖啡");
setPrice(5.0f);
}
}
Milk
public class Milk extends Decorator {
public Milk(Drink obj) {
super(obj);
setDescription("牛奶");
setPrice(2.0f);
}
}
Soy
public class Soy extends Decorator {
public Soy(Drink obj) {
super(obj);
setDescription("豆浆");
setPrice(1.5f);
}
}
JDK源码解析:InputStream装饰者模式
public class DecoratorDemo {
public static void main(String[] args) throws IOException {
/**
* 1、InputStream --> Drink抽象类
* 2、DataInputStream --> Milk装饰者
* 3、FileInputStream --> LongBlack被装饰者
*/
InputStream inputStream = new DataInputStream(new FileInputStream("C:\\Users\\hhdww\\Desktop\\abc.txt"));
System.out.println(inputStream.read());
inputStream.close();
}
}
本文介绍了软件设计中的外观模式和装饰器模式。通过家庭影院系统案例,展示如何使用外观模式简化复杂系统的操作流程;并通过咖啡调料问题,阐述装饰器模式在动态扩展对象功能方面的优势。
427

被折叠的 条评论
为什么被折叠?



