说明
门面模式也叫外观模式,是一种结构型模式。它是一种很容易理解且易于实现的模式,它的定义是这样的:外部与一个子系统内部的通信必须通过一个统一的对象进行,门面模式提供一个高层次的接口, 使得子系统更易于使用。简单的理解就是通过门面模式,我们能很轻松的使用一个子系统,而不必关心子系统内部是怎么去实现的。
应用场景
- 为一个复杂的模块或子系统提供一个供外界访问的接口
- 子系统相对独立–外界对子系统的访问只要黑箱操作即可
- 包装多个复杂的子系统,提供一个简单的接口
- 重新包装系统,隐藏不想暴露的接口
模式特征
- Facade 门面角色: 客户端可以调用这个角色的方法. 此角色知晓子系统的所有功能和责任. 一般情况下, 本角色会将所有从客户端发来的请求委派到相应的子系统去, 也就是说该角色没有实际的业务逻辑, 只是一个委托类。该角色可以是一个具体的类,也可以是一个接口。
- Subsystem 子系统角色: 可以同时有一个或多个子系统. 每一个子系统都不是一个单独的类, 而是一个类的集合.子系统并不知道门面的存在. 对于子系统而言, 门面仅仅是另外一个客户端而已
代码实现
场景:对于不懂电脑的同学A来说,如果想组装一台台式电脑,可能就需要委托懂组装电脑的同学B来了,同学A告诉B自己的预算,然后由B去完成电脑组装,这里B就相当于门面的角色。
- 子系统中的类(Computer、CPU、GraphicsCard、MainBoard、Memory、PowerSupp、Screen)
@Getter
@Setter
public class Computer {
private Cpu cpu;
private GraphicsCard graphicsCard;
private MainBoard mainBoard;
private Memory memory;
private PowerSupply powerSupply;
private Screen screen;
}
public class Cpu {
public Cpu(int price) {
System.out.println("购买了价值"+ price +"的CPU");
}
}
public class GraphicsCard {
public GraphicsCard(int price) {
System.out.println("购买了价值"+ price +"的显卡");
}
}
public class MainBoard {
public MainBoard(int price) {
System.out.println("购买了价值"+ price +"的主板");
}
}
public class Memory {
public Memory(int price) {
System.out.println("购买了价值"+ price +"的内存条");
}
}
public class PowerSupply {
public PowerSupply(int price) {
System.out.println("购买了价值"+ price +"的电源");
}
}
public class Screen {
public Screen(int price) {
System.out.println("购买了价值"+ price +"的显示器");
}
}
- StudentB
public class StudentB {
/**
* 组装电脑
* @param budgetary 电脑预算
*/
public Computer assembleComputer(int budgetary){
//具体金额怎么分配逻辑不做实现
Cpu cpu = new Cpu(500);
GraphicsCard graphicsCard = new GraphicsCard(2000);
MainBoard mainBoard = new MainBoard(1000);
Memory memory = new Memory(800);
PowerSupply powerSupply = new PowerSupply(700);
Screen screen = new Screen(1000);
Computer computer = new Computer();
computer.setCpu(cpu);
computer.setGraphicsCard(graphicsCard);
computer.setMainBoard(mainBoard);
computer.setMemory(memory);
computer.setPowerSupply(powerSupply);
computer.setScreen(screen);
System.out.println("电脑组装完成");
return computer;
}
}
- StudentA
public class StudentA {
public static void main(String[] args) {
StudentB studentB = new StudentB();
studentB.assembleComputer(10000);
}
}
- 结果
购买了价值500的CPU
购买了价值2000的显卡
购买了价值1000的主板
购买了价值800的内存条
购买了价值700的电源
购买了价值1000的显示器
电脑组装完成
优缺点
优点
- 减少系统的相互依赖. 如果不使用门面模式, 外界访问直接深入到子系统内部, 相互之间是一种强耦合关系, 这样的强依赖是系统设计所不能接受的. 门面模式的出项很好的解决了这个问题, 所有的依赖都是对门面对象的依赖, 与子系统无关.
- 减少客户端对子系统的依赖,提高了灵活性
- 提高安全性,针对子系统API,选择性的暴露给客户端
缺点
门面模式最大的缺点就是不符合开闭原则