外观模式
1. 外观模式的定义
外观模式(Facade Pattern)又称为门面模式,它为子系统中的接口提供一个一致的接口,来隐藏子系统内部的复杂性,使得子系统更加容易使用。
外观模式属于结构型模式。它只涉及到一个单一的类,该类提供了客户端调用的简化方法和对现有子系统类方法的委托调用。
2. 外观模式的要点
1)目的
外观模式通过引入一个外观角色来简化客户端与子系统之间的交互,为复杂的子系统调用提供一个一致的接口,降低子系统与客户端的耦合度,且客户端调用非常方便。
2)优点
- 1、松散耦合
- 2、简单易用
- 3、更好地划分访问层次
实现客户端和子系统之间解耦,使子系统内部模块更加容易扩展和维护,子系统的变化不会影响调用它的客户类。
对客户端屏蔽了子系统的组件,减少了客户端处理对象的数目,使用子系统更加容易。
子系统中有些方法是对外开放的,有些方法是系统内部交互使用的。子系统把那些暴露给外部的功能集中到门面中,这样既能保证客户端的使用,也能很好地隐藏了子系统内部的细节。
3)缺点
- 1、违背开闭原则
- 2、增加系统复杂度
增加新的子系统需要修改外观类或客户端的源代码,违背了“开闭原则”。
引入了一个新的外观类,增加了系统的复杂度。
4)使用场景
- 1、为复杂的子系统提供一个外界访问的模块。
- 2、客户端通过外观类使用子系统,子系统相对独立。
- 3、实现客户端与现有子系统隔离,预防外部代码带来风险。
3. 外观模式的范例
外观模式的结构比较简单,主要是定义了一个高层接口。它包含了对各个子系统的引用,客户端可以通过它访问各个子系统的功能。
1)外观模式的结构
a. 外观模式的角色:
- 外观(Facade)角色:为多个子系统对外提供一个共同的接口。
- 子系统(Sub System)角色:实现系统的部分功能,客户可以通过外观角色访问它。
- 客户(Client)角色:通过一个外观角色访问各个子系统的功能。
b. 外观模式的结构图:
2)外观模式的实现
package com.aizws.facade; /** * 调用者客户端 * @author 编程教程 * */ public class Client { public static void main(String[] args) { Facade f = new Facade(); f.method(); } } /** * 外观角色 * @author 编程教程 * */ class Facade { private SubSystem01 s1 = new SubSystem01(); private SubSystem02 s2 = new SubSystem02(); private SubSystem03 s3 = new SubSystem03(); public void method() { s1.method1(); s2.method2(); s3.method3(); } } /** * 子系统角色01 * @author 编程教程 * */ class SubSystem01 { public void method1() { System.out.println("子系统01的method1()被调用!"); } } /** * 子系统角色02 * @author 编程教程 * */ class SubSystem02 { public void method2() { System.out.println("子系统02的method2()被调用!"); } } /** * 子系统角色03 * @author 编程教程 * */ class SubSystem03 { public void method3() { System.out.println("子系统03的method3()被调用!"); } }
4. 模拟计算机的范例
我们使用外观模式,模拟一个计算机系统的例子。
每个 Computer 都有 CPU、Memory、Disk。我们只想使用 Computer,而不要直接跟 CPU、Memory、Disk 这些部件打交道。
这个 Computer 具有开启和关闭功能。 Computer 在 开启和关闭的时候,相应的部件也会开启和关闭。
所以,我们使用了外观模式后,会使用户和计算机部件之间解耦。
package com.aizws.facade; /** * cpu子系统类 * @author 编程教程 * */ public class CPU { public void start() { System.out.println("CPU is starting up..."); } public void shutDown() { System.out.println("CPU is shutting down..."); } } /** * Disk子系统类 * @author 编程教程 * */ public class Disk { public void start() { System.out.println("Disk is starting up..."); } public void shutDown() { System.out.println("Disk is shutting down..."); } } /** * Memory子系统类 * @author 编程教程 * */ public class Memory { public void start() { System.out.println("Memory is starting up..."); } public void shutDown() { System.out.println("Memory is shutting down..."); } } /** * 外观类 * @author 编程教程 * */ public class Computer { private CPU cpu; private Memory memory; private Disk disk; public Computer() { cpu = new CPU(); memory = new Memory(); disk = new Disk(); } public void start() { System.out.println("Computer is starting up"); cpu.start(); disk.start(); memory.start(); } public void shutDown() { System.out.println("Computer is shutting down"); cpu.shutDown(); disk.shutDown(); memory.shutDown(); } } /** * 客户端类 * @author 编程教程 * */ public class Cilent { public static void main(String[] args) { Computer computer = new Computer(); computer.start(); System.out.println("================="); computer.shutDown(); } }