zoukankan      html  css  js  c++  java
  • 设计模式(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 734F Anton and School
    CodeForces 733F Drivers Dissatisfaction
    CodeForces 733C Epidemic in Monstropolis
    ZOJ 3498 Javabeans
    ZOJ 3497 Mistwald
    ZOJ 3495 Lego Bricks
    CodeForces 732F Tourist Reform
    CodeForces 732E Sockets
    CodeForces 731E Funny Game
    CodeForces 731D 80-th Level Archeology
  • 原文地址:https://www.cnblogs.com/xiaoqiangzhaitai/p/5637316.html
Copyright © 2011-2022 走看看