概述
外观模式也成为外观模式,它隐藏系统的复杂性,为子系统中的一组接口提供一个一致的途径,外观模式定义了一个高层接口,使得这一子系统更加容易使用。是为了解决类与类之间的依赖关系的,将类与类的关系放在一个类中,降低了类类之间的耦合度。
涉及角色
- Facade
外观角色:代表构成系统的许多其他角色的简单窗口,向系统外部提供高层接口 - 其他角色:被facade调用的各个api
UML
使用场景
- 为复杂的模块或子系统提供外界访问的模块
- 子系统相对独立:子系统可能会因为重构变得越发复杂,此时可以通过外观模式对外提供一个简单的接口,减少系统之间的依赖
- 预防低水平人员带来的风险:在维护一个遗留的大型系统时,可能这个系统已经变得非常难以维护和扩展,此时可以考虑为新系统开发一个Facade类,来提供遗留系统的比较清晰简单的接口,让新系统与Facade类交互
优点
- 提高了安全性:由于外观模式对外屏蔽了子系统的细节,因此外观模式降低了客户端对子系统使用的复杂性和安全性。
- 减少系统相互依赖:外观模式松散了客户端与子系统的耦合关系,让子系统内部的模块更易维护和扩展。
- 提高灵活性:通过合理的使用外观模式,可以帮我们更好的划分访问的层次
缺点
- 不符合开闭原则,如果要改东西很麻烦,继承重写都不合适
- 过多的或者不合理的使用外观模式容易让人产生困惑,到底是调用Facade好呢还是直接调用模块好
代码示例
如:买台式机电脑,如果没有电脑整机供应商,需要分别买处理器(Cpu)、主板(Board)、硬盘(Disk)、机箱(ComputerCase)、电源(Power)……
现在在引入电脑整机供应商,供应商负责买各种配件,供应商就是外观模式。购买者只需和供应商交流,供应商和各配件厂商进行交流
package com.designpattern.facade;
public class Cpu {
public Cpu() {
// TODO Auto-generated constructor stub
System.err.println("cpu be Ready");
}
}
package com.designpattern.facade;
public class Disk {
public Disk() {
// TODO Auto-generated constructor stub
System.err.println("Disk be Ready");
}
}
package com.designpattern.facade;
public class Board {
public Board() {
// TODO Auto-generated constructor stub
System.err.println("Board be Ready");
}
}
package com.designpattern.facade;
public class ComputerCase {
public ComputerCase() {
// TODO Auto-generated constructor stub
System.err.println("ComputerCase be Ready");
}
}
package com.designpattern.facade;
public class ComputerSupplier{
private Cpu cpu;
private Board board;
private Disk disk;
private ComputerCase computerCase;
public Cpu getCpu() {
return cpu;
}
public Board getBoard() {
return board;
}
public Disk getDisk() {
return disk;
}
public ComputerCase getComputerCase() {
return computerCase;
}
public void setCpu(Cpu cpu) {
this.cpu = cpu;
}
public void setBoard(Board board) {
this.board = board;
}
public void setDisk(Disk disk) {
this.disk = disk;
}
public void setComputerCase(ComputerCase computerCase) {
this.computerCase = computerCase;
}
public void getComputer() {
setCpu(new Cpu());
setDisk(new Disk());
setBoard(new Board());
setComputerCase(new ComputerCase());
}
}
package com.designpattern.facade;
public class TestMain {
public static void main(String[] args) {
ComputerSupplier computerSupplier= new ComputerSupplier();
computerSupplier.getComputer();
}
}
有了这个ComputerSupplier类,那么客户端就不需要亲自调用子系统中的cpu、disk、board、computerCase模块了,也不需要知道系统内部的实现细节,甚至都不需要知道cpu、disk、board、computerCase模块的存在,客户端只需要跟ComputerSupplier类交互就好了,从而更好地实现了客户端和子系统中cpu、disk、board、computerCase模块的解耦,让客户端更容易地使用系统。
外观模式的用意是为子系统提供一个集中化和简化的沟通管道,而不能向子系统加入新的行为