外观模式
其定义为:为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一个子系统更加容易用。
(依然是说的十分抽象。。。)
具体表现为:定义一个Facade外观类,在这个外观类中调用各个子系统的方法或属性。这里的子系统可以理解为与外观类 构成了 聚合 关系。
public class Fund { Stock1 gu1; Stock2 gu2; Stock3 gu3; public Fund(){ gu1 = new Stock1(); gu2 = new Stock2(); gu3 = new Stock3(); } public void buyFund(){ gu1.buy(); gu2.buy(); gu3.buy(); } public void sellFund(){ gu1.sell(); gu2.sell(); gu3.sell(); } } abstract class Stock{ public abstract void buy(); public abstract void sell(); } class Stock1 extends Stock{ @Override public void buy() { } @Override public void sell() { } } class Stock2 extends Stock{ @Override public void buy() { } @Override public void sell() { } } class Stock3 extends Stock{ @Override public void buy() { } @Override public void sell() { } }
上面这段代码里Fund类就是外观类。在其构造函数中初始化各个子系统,并且在它的其他成员方法中调用每个子系统的方法。
看起来是不是有点熟悉。
回忆一下简单工厂模式,其目的是为了操作工厂类得到实际想要的FatherClass的子类对象,具体方法实现是传入一个参数,根据参数用switch或者if进行判断,然后再决定new的是哪个子类对象返回。
两种模式下都是在一个 额外的类中去创建 子系统的对象。不同之处在于简单工厂模式的output是一个子系统对象。而外观模式没有对外返回子系统对象。
外观模式,其目的是为了执行子系统对象中的各个方法,并且把这些子系统和子系统的方法对调用者隐藏掉,由外观类统一处理。new的是所有需要用到的子系统的对象,new的目的是为了执行子系统对象的成员方法。
这种模式其实看起来跟 代理模式有些相像。
看一下代理模式的定义:为其他对象提供一种代理,以控制对这个对象的访问。以java中经典的jdk动态代理为例
public class MyInvovaHandler implements InvocationHandler { private Object target; public MyInvovaHandler(Object target){ this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object obj = method.invoke(target, args);//通过反射调取业务的目标方法 return obj; } }
其目的主要是通过代理类去操作 目标类中的方法,控制被代理类的方法访问。比如A想跟B表白,想让C代理,那么C就通过(反射)去调用A心里的表白方法()。具体怎么表白是由A的内部逻辑决定的,这个调用方法的过程是由C通过反射发起的。
而外观模式侧重于对外部调用者提供简化的方法。只需要A告诉C:我要跟B表白了,你去操作一下。
然后B就马上查子系统资料,该怎么表白,直接自己定义一个void 表白();方法,在里面调用各个子系统 像花店.买花(), 电影院.买电影票(),信.写表白信().....
这里调用的都是子系统的成员方法。
外观模式的适用场景:很多传统的“屎山”项目,在它基础上做扩展或修改,动又不敢动,改也不敢改。可以使用外观模式定义外观类Facade,专门跟这种系统做“交互”,扩展的时候直接去调用Facade中定义的接口。