概述:
Facade模式要求一个子系统的外部与其内部的通信通过一个统一的Facade对象进行。Facade模式提供一个高层次的接口,使得子系统更易于使用。
我的个人理解, 就好像你想吃一道爆炒猪肚,你需要去超市一样一样的买菜,各种配料,外观模式就是超市把所需的菜装在一个盒子里卖给你,你直接买回去扔锅里炒熟就行。不需要关注都要什么类型。
当子系统经过不断的演变,变得异常复杂时,这时候,为了让子系统能够工作,这就要求 客户端对子系统内的各个模块充分了解,才能使各个模块协同工作,达到业务目标。这样无疑增加了客户端的负担。这时候子系统可以为外部定义一个访问的接口,通过接口来完成内部的实现,客户端不需要考虑过多的东西。
案例:
举一个例子,某君要开一个公司,他通过了解,得知注册一个公司大概要经过以下几个步骤:
1.到工商部门申请一个公司名称; // commercialDepartment.applyCompanyName()
2.去银行开一个验资账户 ; // bank.createCheckAccount()
3.准备材料,到工商部门拿营业执照; // commercialDepartment.distributeBusinessLicense()
4. 到公安局备案刻章; // policeBureau.distributeSeal()
5. 到质检局办理组织机构代码证; // qualityInspectionBureau.distributeCertificate()
6. 到税务部门办理税务登记 ; // taxBureau.registerTaxBusiness()
7. 到银行开一个基本账户; // bank.createBasicBank()
8.到税务部门做税种鉴定; // taxBureau.appraiseTaxType()
上面的步骤相信大家都会被吓到:实在太麻烦了!开一个公司需要跑这么多个部门,有的部门还得跑多次,还有就是你要了解这个流程的每一步,对每个部门的具体职责要有很详细的了解,这样才能顺利完成。这个给我们一个非常强烈的感觉:政府机构太臃肿,做一件事怎么就这么难呢!!!!(呵呵,相信大家对这个深有体会吧)
上述的这个流程:主要牵涉到政府的以下几个部门:工商部门、银行、公安局、质检局、税务部门;
在代码里有类似下面的逻辑:对申请者而言,他要持有所有部门的引用,并且对部门的功能有较全面的了解,并且知道这些部门怎么协同工作的。这样无疑增加了额申请者的负担。
- package com.lou.design.pattern.Facade;
- public class Client {
- public void applyRunCompany() {
- // 持有对各个部门的引用
- CommercialDepartment commercialDepartment = new CommercialDepartment();
- Bank bank = new Bank();
- PoliceBureau policeBureau = new PoliceBureau();
- TaxBureau taxBureau = new TaxBureau();
- QualityInspectionBureau qualityInspectionBureau = new QualityInspectionBureau();
- // 申请开公司
- System.out.println("------开始申请开公司........");
- commercialDepartment.applyCompanyName(); //1.到工商部门申请一个公司名称;
- bank.createCheckAccount(); // 2.去银行开一个验资账户 ; //
- commercialDepartment.distributeBusinessLicense(); //3.准备材料,到工商部门拿营业执照;
- policeBureau.distributeSeal(); // 4. 到公安局备案刻章;
- qualityInspectionBureau.distributeCertificate(); // 5. 到质检局办理组织机构代码证;
- taxBureau.registerTaxBusiness(); // 6. 到税务部门办理税务登记 ;
- bank.createBasicBank(); // 7. 到银行开一个基本账户;
- taxBureau.appraiseTaxType(); //8.到税务部门做税种鉴定;
- System.out.println("苍天啊,终于可以开公司了!!!");
- }
- public static void main(String[] args) {
- new Client().applyRunCompany();
- }
- }
- package com.lou.design.pattern.Facade;
- public class Department {
- }
- class CommercialDepartment{
- //工商局其他功能 省略
- public void applyCompanyName()
- {
- System.out.println("工商局:申请一个公司名称。");
- }
- public void distributeBusinessLicense()
- {
- System.out.println("工商局:发放营业执照。");
- }
- //工商局其他功能 省略
- }
- class Bank{
- //银行其他功能 省略
- public void createCheckAccount()
- {
- System.out.println("银行:开一个验资账户。");
- }
- public void createBasicBank()
- {
- System.out.println("银行: 开一个基本账户。");
- }
- //银行其他功能 省略
- }
- class PoliceBureau{
- //其他功能 省略
- public void distributeSeal()
- {
- System.out.println("公安局:备案刻章。");
- }
- //其他功能 省略
- }
- class QualityInspectionBureau{
- //其他功能 省略
- public void distributeCertificate(){
- System.out.println("质检局:办理组织机构代码证。");
- }
- //其他功能 省略
- }
- class TaxBureau{
- //其他功能 省略
- public void registerTaxBusiness()
- {
- System.out.println("税务部门:税务登记。");
- }
- public void appraiseTaxType()
- {
- System.out.println("税务部门:税种鉴定。");
- }
- //其他功能 省略
- }
程序运行结果:
鉴于这一流程太过繁琐,有不少人跟政府反映,政府觉得,应该要对老百姓简化流程,给老百姓解决办事难的问题,所以开设了一个绿色通道,申请者只需要将相关的材料交给这个绿色通道,就可以办完开公司的手续了!(如下图所示)
像这样,政府对外公布一个绿色通道,只需要通过绿色通道提供的服务即可,不需要自己再到不同的部门去申请各式各样的请求了。
虽然说政府简化了申请者的流程,但是本来应该有的流程还是必不可少的,只不过是政府部门自己内部协调处理了。
以下是以上优化的代码展示:
- package com.lou.design.pattern.Facade;
- public class GreenChannel {
- public static void applyRunCompany() {
- // 持有对各个部门的引用
- CommercialDepartment commercialDepartment = new CommercialDepartment();
- Bank bank = new Bank();
- PoliceBureau policeBureau = new PoliceBureau();
- TaxBureau taxBureau = new TaxBureau();
- QualityInspectionBureau qualityInspectionBureau = new QualityInspectionBureau();
- System.out.println("-----------您正在使用政府绿色通道-------------");
- commercialDepartment.applyCompanyName(); //1.到工商部门申请一个公司名称;
- bank.createCheckAccount(); // 2.去银行开一个验资账户 ; //
- commercialDepartment.distributeBusinessLicense(); //3.准备材料,到工商部门拿营业执照;
- policeBureau.distributeSeal(); // 4. 到公安局备案刻章;
- qualityInspectionBureau.distributeCertificate(); // 5. 到质检局办理组织机构代码证;
- taxBureau.registerTaxBusiness(); // 6. 到税务部门办理税务登记 ;
- bank.createBasicBank(); // 7. 到银行开一个基本账户;
- taxBureau.appraiseTaxType(); //8.到税务部门做税种鉴定;
- System.out.println("谢谢您使用政府绿色通道!");
- }
- }
- package com.lou.design.pattern.Facade;
- public class Client {
- public void applyRunCompany() {
- GreenChannel.applyRunCompany();
- }
- public static void main(String[] args) {
- new Client().applyRunCompany();
- }
- }
总结:
一般地, 假设 客户端Client ,和系统内的若干子系统:A,B,C,D…。 现在Client 要完成一项工作,需要A,B,C,D协调完成。
- public class Client{
- public void doSomething()
- {
- A a = new A();
- B b = new B();
- C c = new C();
- D d = new D();
- A.doMethod1();
- B.doMethod2();
- C.doMethod3();
- D.doMethod4();
- // 再做其他的事情
- }
- }
像上面的Client完成doSomething() 所要需要执行四个子系统A,B,C,D的相关功能。这就要求Client对其子系统内部要相当的熟悉,知道其内部功能结构才可以。这样会增加Client的负担,整个子系统也显得臃肿和混乱。如果有更多的Client 想实现这样的功能,这样的代码还要重复敲多少遍啊。
现在可以为子系统增加一个接口,Client只需要通过这个接口,即可完成doSomething()的功能。
- // 将子系统进行封装,给外界提供一个统一的界面接口,不需要Client对子系统要有高要求的了解。
- public class Facade{
- public void service()
- {
- A a = new A();
- B b = new B();
- C c = new C();
- D d = new D();
- A.doMethod1();
- B.doMethod2();
- C.doMethod3();
- D.doMethod4();
- // 再做其他的事情
- }
- }
- //调用子系统提供的门面
- public class Client{
- public void doSomething()
- {
- Facade facade = new Facade();
- facade.service();//门面提供的方法
- }
- }