张三自从毕业后开始做软件开发,做着做着发现不爽了,钱赚不了太多,头发也白了。于是拿着一点小资本,想着做点小生意。瞅着眼前的餐饮行业还不错,于是打算开一家餐馆。开参观可不是一件容易的事,仅仅行政类的审批流程就不少。至少包括办理卫生许可证,办理税务登记,办理工商登记等。
我们先来看一下行政审批接口:
1 interface Executive{ 2
3 public void approve(); 4
5 }
卫生局类的定义:
1 class HealthOffice implements Executive{ 2
3 @Override 4 public void approve() { 5 System.out.println("卫生局通过审批"); 6 } 7
8 }
税务局类的定义:
1 class RevenueOffice implements Executive{ 2
3 @Override 4 public void approve() { 5 System.out.println("税务局完成登记,定时回去收税"); 6 } 7
8 }
工商局类的定义:
1 class SaicOffice implements Executive{ 2
3 @Override 4 public void approve() { 5 System.out.println("工商局完成审核,办法营业执照"); 6 } 7
8 }
好了,现在客户端需要上场了:
1 public class FacadeTest { 2
3 public static void main(String[] args) { 4 System.out.println("开始办理行政手续..."); 5
6 HealthOffice ho = new HealthOffice(); 7 RevenueOffice ro = new RevenueOffice(); 8 SaicOffice so = new SaicOffice(); 9
10 ho.approve(); 11 ro.approve(); 12 so.approve(); 13
14 System.out.println("行政手续终于办完了"); 15 } 16
17 }
当然,上面的各个方法不一定都是实现同一个接口的,只是在这个例子中巧合了下。
我们发现,对客户端而言,想要的最终目的和关心的是办理完开饭店的行政审批手续,如果以办理行政手续为一个子系统来看的话,我们发现,上面的设计中客户端直接与子系统内的多个模块进行了交互,对客户端而言,比较麻烦,使得客户端不能简单的使用系统功能,且随着子系统模块的变换客户端可能也需要随着变化。
我们可以通过外观模式来解决上述问题,外观模式的一般描述是:外观模式定义了一个高层的功能,为子系统中的多个模块协同的完成某种功能需求提供简单的对外功能调用方式,使得这一子系统更加容易被外部使用。
利用外观模式对上述类进行重定义。定义一个外观类:
1 class ApproveFacade { 2
3 public ApproveFacade() { 4
5 } 6
7 public void wholeApprove() { 8 new HealthOffice().approve(); 9 new RevenueOffice().approve(); 10 new SaicOffice().approve(); 11 } 12
13 }
客户端调用:
1 public class FacadeTest { 2
3 public static void main(String[] args) { 4 System.out.println("开始办理行政手续..."); 5
6 ApproveFacade af = new ApproveFacade(); 7 af.wholeApprove(); 8
9 System.out.println("行政手续终于办完了"); 10 } 11
12 }
看,通过外观模式后客户端调用够简单了吧。
外观模式的目的不是给予子系统添加新的功能接口,而是为了让外部减少与子系统内多个模块的交互,松散耦合,从而让外部能够更简单地使用子系统。
外观模式的本质是:封装交互,简化调用。