设计模式(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模式注重稳定接口的前提下为对象扩展功能。

原文地址:https://www.cnblogs.com/xqzt/p/5637064.html