外观模式
概述
提供一个简易的接口,来访问子系统中的一群接口。外观定义了一个高层接口,让子系统容易使用。外观模式是我们封装api的常用手段.外观类中提供了客户端请求的简化方法和对现有系统类方法的委托调用,外观模式是一个结构型设计模式.
UML
Facade
: 系统对外的统一接口SystemA
,System
,SystemC
: 子系统接口.
使用场景
- 为一个复杂子系统提供一个简单接口,子系统往往因为不断演化而变得越来越复杂,甚至可能被替换,facade模式可以提供一个简单统一的接口,对外隐藏子系统的具体实现,隔离变化.
- 当你需要构建一个层次结构的子系统时,使用facade模式定义子系统中每层的入口点.如果子系统之间是相互依赖的,你可以让他们仅通过facade接口通信,从而简化了他们之间的依赖关系.
示例
创建一个类,实例化所有需要设置的对象,然后通过一个命令方法,里面包括了所有的对象的方法,但是只有一个命令入口。只需要调用这一个入口就可以实现所有的设置。
比如我们看家庭影院。我们需要打开电视,打开DVD,打开功放,设置输入模式为DVD,设置声道为双声道,设置房间灯光亮度等等。这么多设置,我们希望将这些动作简化为一次。
需要设置的对象类:
public class Amplifier {
public void on() {
System.out.println("The amplifier is on~");
}
}
public class Light {
public void adjust() {
System.out.println("Adjuast the light~");
}
}
public class Light {
public void adjust() {
System.out.println("Adjuast the light~");
}
}
设置一个类来把这些对象命令包装组合起来
public class HomeTheater {
Amplifier amp;
Light light;
TV tv;
public HomeTheater(Amplifier amp, Light light, TV tv) {
this.amp = amp;
this.light = light;
this.tv = tv;
}
public void WatchMove() {
amp.on();
light.adjust();
tv.on();
}
}
测试类
public class Test {
public static void main(String[] args) {
Amplifier amp = new Amplifier();
Light light = new Light();
TV tv = new TV();
HomeTheater homeTheater = new HomeTheater(amp, light, tv);
homeTheater.WatchMove();
}
}
输出
优缺点
优点
- 对客户端隐藏了子系统的细节,减少客户端对于子系统的耦合,做到拥抱变化
- 外观类对子系统的接口封装,使得子系统更易于使用
缺点
- 外观类接口的膨胀,由于子系统的接口都由外观类统一对外暴露,使得外观类的Api接口增多
- 外观类没有遵循开闭原则,当业务发生变更时,可能需要直接更改外观类.