外观(Facade)模式又称门面模式,感觉这是设计模式中一个比较容易理解的模式,GOF对其所起作用描述为:为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层的接口,这个接口使得这一子系统更加容易使用。Facade的形象化描述可以借用GOF一书中的插图进行表述,如下:
《Java与模式》一书中举了一个例子,就是医院就诊问题,如果说医院是一个系统的话,其中各个室相当于一个子系统,运营管理差的医院可能需要病人自行去办理各个室的业务,运营管理好的医院则可以为病人提供有关接待员,由这个接待员为病人办理相关手续,病人不需要折腾地去与各个室打交道,而且病人也不了解各个室的情况,由接待员办理岂不是效率更高,这个接待员就相当于Facade,也就是医院系统的外观,它能与医院的子系统进行交互,而不需要病人亲自去与子系统交互。
对上述例子的代码实现效果如下:
1 class Patients{ 2 private Server server; 3 public Patients(Server server){ 4 this.server=server; 5 } 6 public void kanbin(){ 7 System.out.println("我要看病"); 8 server.server(); 9 } 10 } 11 class Server{ 12 public void server(){ 13 System.out.println("我是接待员,我来为您服务"); 14 (new GuaHao()).guahao(); 15 (new MenZen()).menzen(); 16 (new HuaJia()).huajia(); 17 (new QuYao()).quyao(); 18 } 19 } 20 class MenZen{ 21 public MenZen(){} 22 public void menzen(){ 23 System.out.println("门诊"); 24 } 25 } 26 class GuaHao{ 27 public GuaHao(){} 28 public void guahao(){ 29 System.out.println("挂号"); 30 } 31 } 32 class QuYao{ 33 public QuYao(){} 34 public void quyao(){ 35 System.out.println("取药"); 36 } 37 } 38 class HuaJia{ 39 public HuaJia(){} 40 public void huajia(){ 41 System.out.println("划价"); 42 } 43 } 44 public class Test{ 45 46 public static void main(String[] args){ 47 Patients p=new Patients(new Server()); 48 p.kanbin(); 49 } 50 }
通常来说,只需要一个Facade,因此Facade的设计经常设计为单例模式,但是这里没给出那么具体的实现,从宏观上讲,外观模式提供的是一种封装,将子系统进行“封装”起来(这些子系统有各自的定义),在设计原则中,有一个“迪米特法则”,就是“只与你直接的朋友通信”,只要可能,朋友越少越好,因为这也就意味着系统耦合度降低,不管怎样,我们都应该尽量避免不必要的直接通信。