外观者模式在生活中的示例很多,比如组装电脑。
组装电脑有两种方式:
第一种方式是用户自己去各个零件商买零件,最终把这些零件拼在一起组成电脑;
第二种方式是找一家专门组装电脑的公司,告诉他们你的具体需求,让他们去帮你完成组装电脑的工作。
可见,第一种方式对用户的要求是很高的,需要用户了解各个组件并且需要考虑这些零件的兼容性;而第二种方式中,用户只需要告诉组装公司自己需要干什么,让组装公司去帮助自己完成就好了。第二种方式更加常见一些,原因是这种方式很简单,而且可行。
这这个例子中组装电脑的公司就相当于今天要讨论的外观者
外观者模式的作用可以总结成一句话:为外部系统提供一个界面
外观者模式:为系统外部提供一个界面。外观者让外部系统在不需要了解内部逻辑和组成的情况下实现功能。实现了外部系统与内部系统的封装隔离,松散了系统间的耦合。
案例:代码生成
public class ModelConfig { private boolean needGenPresentation = true; private boolean needGenBusiness = true; private boolean needGenDAO = true; public boolean isNeedGenPresentation() { return needGenPresentation; } public void setNeedGenPresentation(boolean needGenPresentation) { this.needGenPresentation = needGenPresentation; } public boolean isNeedGenBusiness() { return needGenBusiness; } public void setNeedGenBusiness(boolean needGenBusiness) { this.needNeedGenBusiness = needGenBusiness; } public boolean isNeedGenDAO() { return needGenDAO; } public void setNeedGenDAO() { this.needGenDAO = needGenDAO; } } public class ConfigManager { private static ConfigManager manager = null; private static ConfigModel cm = null; private ConfigManager() { } public static ConfigManager getInstance() { if(manager == null) { manager = new ConfigManager(); cm = new ConfigModel(); } return manager; } public ConfigModel getConfigData() { return cm; } } public class Presentation { public void generate() { ConfigModel cm = ConfigManager.getInstance().getConfigData(); if(cm.isNeedGenPresentation()) { System.out.println("正在生成表现成代码"); } } } public class Business { public void generate() { ConfigModel cm = ConfigManager.getInstance().getConfigData(); if(cm.isNeedGenBusiness()) { System.out.println("正在生成业务层代码"); } } } public class DAO { public void generate() { ConfigModel cm = ConfigManager.getInstance().getConfigData(); if(cm.isNeedGenDAO()) { System.out.println("正在生成数据层代码"); } } } public class Client { public static void main(String[] args) { new Presentation().generate(); new Business().generate(); new DAO().generate(); } }
public class Facade { public void function generate() { new Presentation().generate(); new Business().generate(); new DAO().generate(); } } public class Client { public static void main(String[] args) { new Facade().generate(); } }这样的话,客户端就只需要直接调用Facade进行操作就可以了,而不需要担心各个模块内部的具体实现。
但是,如果客户端除了要调用组合方法外,有时需要直接调用某个模块该怎么办呢,以下还有更好的方式:
public interface AModuleApi { public void a1();//给外部系统调用 public void a2();//给内部调用 public void a3();//给内部调用 } public interface BModuleApi { public void b1();//给外部系统调用 public void b2();//给内部调用 public void b3();//给内部调用 } public interface CModuleApi { public void c1();//给外部系统调用 public void c2();//给内部调用 public void c3();//给内部调用 } public interface FacadeApi { public void a1();//这是各个模块提供给客户端调用的接口 public void b1();//这是各个模块提供给客户端调用的接口 public void c1();//这是各个模块提供给客户端调用的接口 public void test();//这是对外提供的组合接口 } public class Client { public static void main(String[] args) { FacadeApi facade = new FacadeImpl(); facade.a1(); facade.b1(); facade.c1(); facade.test(); } }
外观模式优缺点:
优点:松散耦合,简单易用,更好地划分访问的层次
缺点:容易让人疑惑,到底是调用Facade好呢还是直接调用模块好呢,就好比一个人组装好电脑后,想要扩充内存,到底是找中间公司呢还是自己去买个内存条加上呢。。。
设计模式入门之外观者模式Facade,布布扣,bubuko.com
原文:http://blog.csdn.net/herewjxiang/article/details/22325109