• 设计模式(4)>外观模式 小强斋


    Facade模式

    一、定义

    为子系统中的一组接口提供一个统一接口。Facade模式定义了一个更高层的接口,使子系统更加容易使用。

    二、例子1

          大致意思是说:使用一种比原有方式更简单的办法与系统交互。例如,我们把一个很文件的文件,放在了第二抽屉里,而第二个抽屉的钥匙放在了第一个抽屉里,我们要想取出这个文件,第一步肯定要拿到第一个抽屉的钥匙,然后打开它再拿出第二个抽屉的钥匙,最后打开第二个抽屉取出文件。

     我就上面说的那个情形写一下实现代码,首先我们要实现二个子系统,呵呵,把抽屉比喻成系统,(DrawerOneDrawerTwo):

    子系统1

    class DrawerOne {
    
    	public void open() {
    
    		System.out.println("第一个抽屉被打开了");
    
    		getKey();
    
    	}
    
    	public void getKey() {
    
    		System.out.println("得到第二个抽屉的钥匙");
    
    	}
    
    }

    子系统2

    class DrawerTwo {
    
    	public void open() {
    
    		System.out.println("第二个抽屉被打开了");
    
    		getFile();
    
    	}
    
    	public void getFile() {
    
    		System.out.println("得到这个重要文件");
    
    	}
    
    }

    不使用Façade模式的情况

    public class Client {
    
    	public static void main(String[] args) {
    
    		DrawerOne darwerOne = new DrawerOne();
    
    		DrawerTwo darwerTwo = new DrawerTwo();
    
    		darwerOne.open();
    
    		darwerTwo.open();
    
    	}
    
    }

    由于没有使用Façade模式,可以看到要想得到这个文件要首先打开第一个抽屉,然后再打开第二个抽屉,在我们实际所开发的系统中,有时候客户要实现某一操作,并不需要知道实现这一操作的详细步骤,而是简单地点击某一个按钮就可以得到自己想要的结果。

    使用Façade模式进行改进建立一个FacadeDrawer类:

    class DrawerFacade {
    
    	DrawerOne darwerOne = new DrawerOne();
    
    	DrawerTwo darwerTwo = new DrawerTwo();
    
    	public void open() {
    
    		darwerOne.open();
    
    		darwerTwo.open();
    
    	}
    
    }

    修改Client类:

    public class DrawerClient{
    
       public static void main(String []args){
    
          DrawerFacade drawer=new DrawerFacade();
    
          drawer.open();
    
       }
    
    }

    输出结果如下:

    第一个抽屉被打开了

    得到第二个抽屉的钥匙

    第二个抽屉被打开了

    得到这个重要文件

    正如上面所说,客户端client,它并不需要关心子系统,而是关心DrawerFacade所留下来的和外部交互的接口,而子系统在DrawerFacade的聚合

    三、例子2

    A系统有A1, A2, A3等类。客户端需要调用A系统的的A1.doSomething1();A2.doSomething2();A3.doSomething3()三个方法来完成某功能。Facade模式的实现模型就是:

    A1

    class A1 {
    	public void doSomething1() {}
    }

    A2

    class A2 {
    	public void doSomething2() {}
    }

    A3

    class A3 {
    	public void doSomething3() {}
    }

    Facade:

    public class Facade {
    	public void doSomething() {
    		A1 a1 = new A1();
    		A1 a2 = new A2();
    		A1 a3 = new A3();
    
    		a1.doSomething1();
    		a2.doSomething2();
    		a3.doSomething3();
    	}
    }
    

    Client:

    public class Client {
    	public static void main(String[] args) {
    		Facade facade = new Facade();
    		facade.doSomething();
    	}
    }

    四、适用性

    Facade模式主要适用于以下几种情况:

    1.  为一个复杂子系统提供一个简单接口。

    当你要为一个复杂子系统提供一个简单接口时。子系统往往因为不断演化而变得越来越复杂。大多数模式使用时都会产生更多更小的类。这使得子系统更具可重用性,也更容易对子系统进行定制,但这也给那些不需要定制子系统的用户带来一些使用上的困难。Facade 可以提供一个简单的缺省视图,这一视图对大多数用户来说已经足够,而那些需要更多的可定制性的用户可以越过facade层。

    2.提高子系统的独立性

    客户程序与抽象类的实现部分之间存在着很大的依赖性。引入facade 将这个子系统与客户以及其他的子系统分离,可以提高子系统的独立性和可移植性。

    3.在层次化结构中,可以使用Facade模式定义系统中每一层的入口。

    当你需要构建一个层次结构的子系统时,使用facade模式定义子系统中每层的入口点。如果子系统之间是相互依赖的,你可以让它们仅通过facade进行通讯,从而简化了它们之间的依赖关系。

    4.希望使用原系统的功能,而且还希望增加一些新的功能。

    五、Facade的几个要点

      从客户程序的角度来看,Facade模式不仅简化了整个组件系统的接口,同时对于组件内部与外部客户程序来说,从某种程度上也达到了一种“解耦”的效果——内部子系统的任何变化不会影响到Façade接口的变化。  

     Façade设计模式更注重从架构的层次去看整个系统,而不是单个类的层次。Façade很多时候更是一种架构设计模式。 

     Façade设计模式并非一个集装箱,可以任意地放进任何多个对象。Façade模式中组件的内部应该是“相互耦合关系比较大的一系列组件”,而不是一个简单的功能集合。  

      注意区分Façade模式、Adapter模式、Bridge模式与Decorator模式。Façade模式注重简化接口,Adapter模式注重转换接口,Bridge模式注重分离接口(抽象)与其实现,Decorator模式注重稳定接口的前提下为对象扩展功能。

  • 相关阅读:
    codeforces 37 E. Trial for Chief【spfa】
    bzoj 1999: [Noip2007]Core树网的核【树的直径+单调队列】
    codehunter 「Adera 6」杯省选模拟赛 网络升级 【树形dp】
    codeforces GYM 100781A【树的直径】
    bzoj 2878: [Noi2012]迷失游乐园【树上期望dp+基环树】
    bzoj 1791: [Ioi2008]Island 岛屿【基环树+单调队列优化dp】
    codeforces 949C
    codeforces 402E
    poj 3613 Cow Relays【矩阵快速幂+Floyd】
    bzoj 2097: [Usaco2010 Dec]Exercise 奶牛健美操【二分+树形dp】
  • 原文地址:https://www.cnblogs.com/xiaoqiangzhaitai/p/5429340.html
Copyright © 2020-2023  润新知