`
wangwengcn
  • 浏览: 172972 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

17.门面模式(FacadePattern)

阅读更多

1.定义

要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。
门面模式提供一个高层次的接口,使得子系统更易于使用。
门面模式注重“统一的对象”,也就是提供一个访问子系统的接口,除了这个接口不允许有任何访问子系统的行为发生。
门面对象是外界访问子系统内部的唯一通道,不管子系统内部是多么杂乱无章,只要有门面在,就可以做到“金玉其外败絮其中”。

 

2.门面模式的使用场景

  •  为一个复杂的模块或子系统提供一个工外界访问的接口
  • 子系统相对独立-外界对子系统的访问只要黑箱操作就行了
  • 预防低水平人员带来的风险扩散

门面模式很简单,无非就是对外只提供一个门面暴露外界需要的API,请看下面的通用代码

 

package _17FacadePattern;

/**
 * 子系统中的A业务
 */
public class ClassA {

	public void doSomethingA() {
		
	}
}

 

package _17FacadePattern;

/**
 * 子系统中的B业务
 */
public class ClassB {

	public void doSomethingB() {
		
	}
}

 

package _17FacadePattern;

/**
 * 子系统中的门面1,只暴露外界需要的API
 */
public class Facade {

	private ClassA classA = new ClassA();
	private ClassB classB = new ClassB();
	
	// 对外暴露的API
	public void methodA() 
	{
		classA.doSomethingA();
	}
	public void methodB() 
	{
		classB.doSomethingB();
	}
}

 

 

3.门面模式的两个角色

  • Facade门面角色:客户端可以调用这个角色的方法。此角色知道子系统的所有功能和责任。一般情况下,本角色会将所有从客户端发来的请求委派到相应的子系统中去,也就是说该角色没有实际的业务逻辑,只是一个委托类
  • subsystem子系统角色:可以同时有一个或多个子系统。每个子系统都不是一个单独的类,而是一个类的集合。子系统不知道门面的存在,对子系统来说门面仅仅是另一个客户端而已。

4.门面模式的优点

  • 减少系统的相互依赖:外界只对门面的API产生依赖,而对子系统内部完全解耦。
  • 提高了灵活性:依赖减少了,灵活性自然提高了。不管子系统内部如何变化,只要不影响门面对象,任你自由活动。
  • 提高安全性:想让你访问子系统的哪些业务就开通哪些逻辑,不在门面上开通的方法,你休想访问。

5.门面模式的缺点

门面模式的最大缺点就是不符合开闭原则,对修改关闭,对扩展开放,看看我们的门面对象,它可是重中之重,一旦系统投产后发现有一个小错误,怎么解决?完全遵照开闭原则根本无法解决。继承和覆盖都顶不上用。唯一能做的就是修改门面角色的代码,这个风险很大。

 

6.门面模式的注意事项
6.1什么时候一个子系统需要多个门面

  • 门面已经庞大到不能忍受的程度:当一个类的代码有好几千行的时候,我觉得你很好理解。
  • 子系统可以提供不同的访问路径:上面的通用代码中Facade类对外暴露了ClassA、ClassB、ClassC的所有API,但是这些API我可能只想暴露给X客户端,至于给Y客户端我只想暴露ClassB的API,怎么实现?请看下面代码:
package _17FacadePattern;

/**
 * 子系统中的门面2,对外暴露ClassB的API
 */
public class Facade2 {

	private Facade facade = new Facade();
	
	// 对外暴露ClassB的API
	public void methodB() 
	{
		facade.methodB();
	}
}

 

 

增加的门面很简单,委托给了已经存在的门面对象Facade进行处理,为什么要是有委托而不再编写一个委托到子系统的方法呢?那是因为在面向对象编程中,尽量保持相同的代码只写一遍,避免以后到处修改相似代码的悲剧。

 

6.2门面不参与子系统的内的业务逻辑

这是什么意思呢,请看下面代码:

 

package _17FacadePattern;

/**
 * 子系统中的门面3,门面中包含了业务
 */
public class Facade3 {

	private ClassA classA = new ClassA();
	private ClassB classB = new ClassB();
	
	// 对外暴露的API
	public void methodA() 
	{
		classA.doSomethingA();
	}
	public void methodB() 
	{
		classA.doSomethingA();
		classB.doSomethingB();
	}
}

 

 

因为某个需求更改,我们在门面的methodC里面调用了另一个方法。其实这样的设计是非常不靠谱的,为什么呢?因为你已经让门面对象参与了业务逻辑,门面对象只是提供一个访问子系统的路径而已,它不应该也不能参与具体的业务逻辑,否则就会产生一个倒依赖的问题,子系统必须依赖门面才能被访问,这是设计上的一个严重错误,不仅违背了单一职责原则,同时也破坏了系统的封装性。
好吧,说了这么多,让我们看看应该怎么改:
先将methodC的逻辑封装到另一个类中

 

package _17FacadePattern;

/**
 * 业务的封装类
 */
public class Context {

	private ClassA classA = new ClassA();
	private ClassB classB = new ClassB();
	
	// 对外暴露的API
	public void methodB() 
	{
		classA.doSomethingA();
		classB.doSomethingB();
	}
}

 

 

然后门面中调用封装类:

 

package _17FacadePattern;

/**
 * 子系统中的门面4,将3中包含的业务逻辑封装到一个业务类中
 */
public class Facade4 {

	private ClassA classA = new ClassA();
	private Context context = new Context();
	
	// 对外暴露的API
	public void methodA() 
	{
		classA.doSomethingA();
	}
	public void methodB() 
	{
		context.methodB();
	}
}

 

 

通过这样一次封装后,门面对象又不参与业务了,在门面模式中,门面角色应该是稳定的,它不应该经常变化,一个系统一旦投入运行,它就不应该被改变,它是一个系统对外的接口,你经常变化怎么保证其他模块的稳定运行呢?但是,业务逻辑是经常改变的,我们已经把它封装在子系统内部,无论你如何变化,对外界的访问者来说,都还是同一个门面,同样的方法-这才是架构师最希望看到的结构。

分享到:
评论

相关推荐

    设计模式 之 “门面模式[Facade Pattern]”

    NULL 博文链接:https://lym6520.iteye.com/blog/707060

    Java24种设计模式,Java24种设计模式,24种设计模式,学会了这24种设计模式,可以打遍天下无敌手,设计模式非常重要

    7、门面模式FACADE PATTERN 8、适配器模式ADAPTER PATTERN 9、模板方法模式TEMPLATE METHOD PATTERN 10、建造者模式BUILDER PATTERN 11、桥梁模式BRIDGE PATTERN 12、命令模式COMMAND PATTERN 13、装饰模式...

    解析C#设计模式编程中外观模式Facade Pattern的应用

    主要介绍了C#设计模式编程中外观模式Facade Pattern的应用,外观模式中分为门面(Facade)和子系统(subsystem)两个角色来进行实现,需要的朋友可以参考下

    Java设计模式

    第 7 章 门面模式【FACADE PATTERN】 .................................................................................................... 44 第 8 章 适配器模式【ADAPTER PATTERN】 ..........................

    24种设计模式与6大设计原则

    门面模式[FACADE PATTERN] 适配器模式[ADAPTER PATTERN] 模板方法模式[TEMPLATE METHOD PATTERN] 建造者模式[BUILDER PATTERN] 策略模式 代理模式 单例模式 多例模式 工厂方法模式 抽象工厂模式 门面模式 适配器...

    JAVA设计模式.rar

    门面模式【FACADE PATTERN】  适配器模式【ADAPTER PATTERN】  模板方法模式【TEMPLATE METHOD PATTERN】  建造者模式【BUILDER PATTERN】 桥梁模式【BRIDGE PATTERN】  命令模式【COMMAND PATTERN...

    详解PHP中的外观模式facade pattern

    facade这个词,原意指的是一个建筑物的表面、外观,在建筑学中被翻译为“立面”这个术语,国内对facade这个词的关注,可能更多要依赖于laravel的流行,似乎都一致把laravel里的facade翻译作“门面”。说实在的,当第...

    php设计模式 Facade(外观模式)

    模式定义:外观模式(Facade Pattern):外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。...

    网络编程、常用设计模式

    一、门面模式(Facade Pattern) 23 二、门面模式的结构 24 三、在什么情况下使用门面模式 24 【五】、适配器模式 25 一、适配器模式(Adapter Pattern) 25 二、类的Adapter模式的结构 25 三、对象的Adapter模式的结构 ...

    C#设计模式.PDF

    设计模式(17)-Chain of Responsibility Pattern 158 一、 职责链(Chain of Responsibility)模式 160 二、 责任链模式的结构 160 三、 责任链模式的示意性源代码 160 四、 纯的与不纯的责任链模式 163 五、 责任...

    第14章_外观模式.ppt

    外观模式(Facade Pattern):外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。外观模式又称为...

    软件开发中的23种设计模式

    23种模式(Pattern) 1、创建形模式: 1)、单用型:Singleton 2)、工厂方法型:Factory Method...3)、门面模式:Facade 4)、装饰模式:Decorator 3、行为型模式 1)、策略模式:Strategy 2)、观察者模式:Observer

    C#设计模式大全

    设计模式(17)-Chain of Responsibility Pattern 一、 职责链(Chain of Responsibility)模式 二、 责任链模式的结构 三、 责任链模式的示意性源代码 四、 纯的与不纯的责任链模式 五、 责任链模式的实际...

    24个设计模式与6大设计原则

    第 7 章 门面模式【FACADE PATTERN】 44 第 8 章 适配器模式【ADAPTER PATTERN】 51 第 9 章 模板方法模式【TEMPLATE METHOD PATTERN】 63 第 10 章 建造者模式【BUILDER PATTERN】 82 第 11 章...

    二十三种设计模式【PDF版】

    设计模式之 Facade(门面?) 可扩展的使用 JDBC针对不同的数据库编程,Facade提供了一种灵活的实现. 设计模式之 Composite(组合) 就是将类用树形结构组合成一个单位.你向别人介绍你是某单位,你是单位中的一个元素...

    java 面试题 总结

    17、abstract class和interface有什么区别? 声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建...

    超级有影响力霸气的Java面试题大全文档

    17、Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?  方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是...

    Medusa:美杜莎(Medusa)是发布书评的网站。 它有两个面板

    Net Core MVC API和/或ASP.Net Net Core MVC和/或Swagger 存储库模式-依赖注入模式-工作单元模式-适配器设计模式-选项模式-门面设计模式-内存缓存-Fluent API-NLog-自动映射器-Bootstap && Bootswatch 有用的网站:...

Global site tag (gtag.js) - Google Analytics