顿搜
外观模式/门面模式——23种设计模式之结构型模式
客户代码与组件中各种复杂的子系统有较多的耦合, 随着外部客户程序和各子系统的演化,这种过多的耦合面临着很多变化的挑战。如何“简化外部客户程序和系统间的交互接口” ?如何将外部客户程序的演化和内部子系统的变化之间的依赖相互解耦?
外部与一个子系统的通信必须通过一个统一的 门面(Façade)对象进行,这就是门面模式。
门面模式要求一个子系统的外部与其内部的通信必须 通过一个统一的门面(Façade)对象进行。门面模式提 供一个高层次的接口,使得子系统更易于使用。
解决的问题:
外观模式是为了解决类与类之间的依赖关系。降低类与类之间的耦合度,方便第三方使用
传统方法问题所在:
在大型项目中,对象与对象之间需要同步做一些事情,第三方在使用系统时,需要和系统中的每个对象进行交互。这样耦合度高,不利于使用和扩展。
模式思想:
在系统之上添加一个对外的界面,并提供尽量少的接口给第三方使用。这样对外暴露的对象和操作大大减少,不仅方便了第三方的使用,也降低了对象与对象之间的耦合。以下是外观模式的一个例子。
一、类图表示
门面模式涉及到门面(Façade)和子系统(Subsystem)两个角色
- ①、门面(Façade)角色:客户端可以调用这个角色的方法。 此角色知晓相关的(一个或者多个)子系统的功能和责 任。在正常情况下,本角色会将所有从客户端发来的 请求委派到相应的子系统去。
- ②、子系统(subsystem)角色:可以同时有一个或者多个子系统。每一个子系统都不是一个单独的类,而是一个类的集合。每一个子系统都可以被客户端直接调用,或者被门面角色调用。子系统并不知道门面的存在, 对于子系统而言,门面仅仅是另外一个客户端而已。
二、代码示例
//A类别
public class A{
public void on(){
System.out.println("A on");
}
public void off(){
System.out.println("A off");
}
}//B类别
public class B{
public void startUp(){
System.out.println("B startUp");
}
public void shutDown(){
System.out.println("B shutDown");
}
}//C类别
public class C{
public void run(){
System.out.println("c run");
}
public void stop(){
System.out.println("c stop");
}
}//外观
public class Facade{
private A a;
private B b;
Private C c;
public Facade(){
a = new A();
b = new B();
c= new C();
}
public void action_1(){
a.on();
b.startUp();
c.run();
}
public void action_2(){
a.off();
b.shutDown();
c.stop();
}
}//测试类
public class Test{
public static void main(String[] args){
Facade facade = new Facade();
facade.action_1();
facade.action_2();
}
}三、模式分析
1、设计原则分析
- ①、根据“单一职责原则”,在软件中将一个系统划分为若干个子系统有利于降低整个系统的复杂性,一 个常见的设计目标是使子系统间的通信和相互依赖关系达到最小,而达到该目标的途径之一就是引入一个外观对象,它为子系统的访问提供了一个简单 而单一的入口。
- ②、门面模式也是“迪米特法则”的体现,通过引入一个新的外观类可以降低原有系统的复杂度,同时降低客户类与子系统类的耦合度。
2、优点
- ①、门面模式要求一个子系统的外部与其内部的通信通过一个统一的外观对象进行,外观类将客户端与子系统的内部复杂性分隔开,使得客户端只需要与外 观对象打交道,而不需要与子系统内部的很多对象打交道。
- ②、门面模式的目的在于降低系统的复杂程度。
- ③、门面模式从很大程度上提高了客户端使用的便捷性, 使得客户端无须关心子系统的工作细节,通过外观角色即可调用相关功能。
四、模式间关系
1、与抽象工厂模式之间的关系
- ①、Abstract Factory模式可以与Façade模式一起使用以提供一个接口,这一接口可用来以一种子系统独立的方式创建子系统对象。
2、与调停者模式的关系
- ①、Mediator模式与Façade模式的相似之处是,它抽象了一些已有的类的功能。
3、与单例模式的关系
- ①、通常仅需要一个Façade对象,因此可以用 Singleton模式
4、与命令模式的区别
- ①、命令模式侧重将命令封装成对象,这样达到控制者,命令和执行者之间解耦;
- ②、外观模式侧重让系统的使用更简单,操作更少。
- ③、命令模式中,宏命令的目的和外观模式一样。
五、应用场景
一个复杂子系统需要一个简单接口
- ①、需要提高子系统的独立性
- ②、在层次化结构中,可以使用Facade模式定义系统中每 一层的入口。
六、总结
实现了子系统与客户端之间的解耦
- ①、它实现了子系统与客户之间的松耦合关系,而子系统内部的功能组件往往是紧耦合的。②、用抽象类实现 Façade而它的具体子类对应于不同的子系统实现可以进一步解耦;另一种方法是用不同的子 系统对象配置Façade对象。
- ③、从客户程序的角度来看,Façade模式不仅简化 了整个组件系统的接口,同时对于组件内部与 外部客户程序来说,从某种程度上也达到了一 种“解耦”的效果
- ④、Façade 模式更注重从架构的层次去看整个系统, 而不是单个类的层次。 Façade 很多时候更是一 种架构设计模式。
