经过一段时间的努力之后,小成的两间注塑厂生意终于走上正轨了,但是这样的代价就是要他每天都在两间距离并不算近的注塑厂之间跑来跑去,接到一个订单,跑到A厂去布置生产工作,又跑去B厂,生产完成了又要去布置配送任务,然后又接收的工作汇报,真的分身乏术。还好他的合伙人见他这么麻烦就给他在外面租了一间办公室当办事处,在这个办事处里管理两个厂的工作,等两个工厂的负责人来领工作和汇报工作完成情况就行了。
后来小成悠闲地坐在办事处里想一想,这不就是设计模式里的外观模式吗,两个注塑厂办事处就是“外观”,然后他就开始写代码了:
介绍
根据“单一职责原则”,在软件中往往会将一个系统划分为若干个子系统有利于降低整个系统的复杂性,但是过多了子系统也会增加系统的使用难度,所以需要一个简单而单一的入口来统一调用,这个就是外观模式。客户端只需要与外观对象打交道,而不需要与子系统内部的很多对象打交道。
外观模式的定义是:为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一个子系统更加容易使用。外观类充当了客户类与子系统类之间的“第三者”,同时降低客户类与子系统类的耦合度。在下面的代码中,两个工厂类组成子系统,办事处FactoryOffice类就是提供的高层接口,通过调用这个接口,使用者可以方便地调用子系统的方法。
代码:
package scut.designmodel.FacadePattern;
//工厂A的工作
class MoldingFactoryA {
public void ProductAManufacture(){
System.out.println("注塑产品工厂A生产产品!");
}
public void ProductADelivery(){
System.out.println("注塑产品工厂A配送产品!");
}
public void ProductAReport(){
System.out.println("注塑产品工厂A汇报工作!");
}
}
//工厂B的工作
class MoldingFactoryB {
public void ProducrBManufacture(){
System.out.println("注塑产品工厂B生产产品!");
}
public void ProductBDelivery(){
System.out.println("注塑产品工厂B配送产品!");
}
public void ProductBReport(){
System.out.println("注塑产品工厂B汇报工作!");
}
}
//工厂办事处,也就是两个加工厂的“外观”
class FactoryOffice{
MoldingFactoryA mmoldingFactoryA;
MoldingFactoryB mmoldingFactoryB;
//构造函数建造工厂实例
public FactoryOffice(){
mmoldingFactoryA = new MoldingFactoryA();
mmoldingFactoryB = new MoldingFactoryB();
}
//管理工厂生产
public void FactoryManufacture(){
mmoldingFactoryA.ProductAManufacture();
mmoldingFactoryB.ProducrBManufacture();
}
//管理工厂配送
public void FactoryDelivery(){
mmoldingFactoryA.ProductADelivery();
mmoldingFactoryB.ProductBDelivery();
}
//管理工厂汇报
public void FactoryReport(){
mmoldingFactoryA.ProductAReport();
mmoldingFactoryB.ProductBReport();
}
}
public class FacadePattern {
//小成老板用办事处管理两间工厂的工作
public static void main(String[] arg){
FactoryOffice mfactoryOffice = new FactoryOffice();
mfactoryOffice.FactoryManufacture();
mfactoryOffice.FactoryDelivery();
mfactoryOffice.FactoryReport();
}
}
运行结果:
注塑产品工厂A生产产品!
注塑产品工厂B生产产品!
注塑产品工厂A配送产品!
注塑产品工厂B配送产品!
注塑产品工厂A汇报工作!
注塑产品工厂B汇报工作!
应用场景
- 当一些为一个复杂子系统提供一个简单的接口时。
- 当客户端与抽象类的实现部分之间存在着很大的依赖性时。
- 当需要构建一个层次结构的子系统时。
优点
- 对客户屏蔽子系统组件,减少了客户处理的对象数目并使得子系统使用起来更加容易。
- 实现了子系统与客户之间的松耦合关系,符合迪米特法则,这使得子系统的组件变化不会影响到调用它的客户类,只需要调整外观类即可。
缺点
- 不能很好地限制客户使用子系统类,如果对客户访问子系统类做太多的限制则减少了可变性和灵活性。
- 在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。
参考
- http://blog.csdn.net/hguisu/article/details/7533759
- http://design-patterns.readthedocs.io/zh_CN/latest/structural_patterns/facade.html
- 《设计模式其实很简单》,刘径舟,张玉华等编著——清华大学出版社,2013.7