一、概念
引入一个外观角色来化简客户端与子系统之间的操作,为复杂的子系统调用提供一个统一的入口,使子系统和客户端的耦合度降低,且客户端调用非常方便。
二、角色
1.外观角色 Facade
在客户端可以调用这个角色的方法,在外观角色中可以知道相关的子系统的功能和责任,在正常情况下,它将所有客户端发来的请求委派到相应的子系统去,传递给相应的子系统对象处理。
2.子系统角色 SubSystem
一个或多个,每一个子系统可以不是一个单独的类,而是一个类的集合,它实现子系统的功能;每个子系统都可以被客户端直接调用或者被外观角色调用。
举例说明:一个网站的首页有很多功能(新闻、留言等),可以通过这个首页进入功能页,首页就是外观角色,没有这个外观角色,就需要记住各种各样的功能页网址,而有了首页,通过一个首页就可以访问各种各样的功能页。相当于用首页这个外观角色把子系统角色包装起来丢给客户端。
三、代码说明
在计算机主机(Mainframe)中,只需要按下主机的开关按钮,即可调用其他硬件设备和软件设备的启动方法,如内存(Memory)的自检(check())、CPU的运行(run()),硬盘(HardDisk)的读取(read())、操作系统OS的载入(load())等,如果某一过程发生错误则启动失败。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package waiguan; public class Mainframe { private Memory memory=new Memory(); private CPU cpu=new CPU(); private HardDisk hardDisk=new HardDisk(); private OS os=new OS(); public void on() { memory.check(); cpu.run(); hardDisk.read(); os.load(); } } class Memory{ public void check() { System.out.println("内存自检启动。。。"); } } class CPU{ public void run() { System.out.println("CPU开始运行。。。"); } } class HardDisk{ public void read() { System.out.println("硬盘读取开始。。。"); } } class OS{ public void load() { System.out.println("OS开始载入。。。"); } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package waiguan; public class Client { public static void main(String[] args) { System.out.println("通过外观角色启动计算机:"); Mainframe mainframe=new Mainframe(); mainframe.on(); System.out.println("..............................................."); System.out.println("通过子系统角色启动计算机:"); Memory memory=new Memory(); CPU cpu=new CPU(); HardDisk hardDisk=new HardDisk(); OS os=new OS(); memory.check(); cpu.run(); hardDisk.read(); os.load(); } }
输出:
通过外观角色启动计算机:
内存自检启动。。。
CPU开始运行。。。
硬盘读取开始。。。
OS开始载入。。。
...............................................
通过子系统角色启动计算机:
内存自检启动。。。
CPU开始运行。。。
硬盘读取开始。。。
OS开始载入。。。
按照书上的例子模仿出来,大概就是这样,不让客户端显得太复杂,外观角色的方法只是把子系统角色的方法装在一起而已。
四、优缺点
- 优点:实现了客户端和子系统的松藕关系,子系统组件的变化不会影响到客户端,只需要调整外观类。
- 缺点:调整外观类需要改动原来的代码,违背“开闭原则”。
- 改进:引入抽象外观类(多写一个类和方法存放调整后的外观类)