设计模式十四--外观模式

558 阅读3分钟

这是我参与更文挑战的第27天,活动详情查看: 更文挑战

设计模式

外观模式

外观模式又叫作门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。

举个例子,我们买车需要交税、上牌、买保险等等过程(多个复杂的子系统),这些过程就是子系统角色,但是呢,这些过程没必要我们自己去处理,卖车销售会帮你去处理,这里销售就充当了外观角色,而我们这些买车的人就是客户角色。

首先子系统一交税PayTaxes:包括填写资料、交钱,获取发票等等步骤

package com.wangscaler.facade;

/**
 * @author wangscaler
 * @date 2021.06.29 14:39
 */
public class PayTaxes {
    private static PayTaxes instance = new PayTaxes();

    public static PayTaxes getInstance() {
        return instance;
    }

    public void write() {
        System.out.println("填写资料");
    }

    public void pay() {
        System.out.println("成功交税");
    }

    public void invoice() {
        System.out.println("恭喜获得发票");
    }
}

子系统二上牌License:包括交钱、验车、获取车牌等等步骤

package com.wangscaler.facade;

/**
 * @author wangscaler
 * @date 2021.06.29 14:39
 */
public class License {
    private static License instance = new License();

    public static License getInstance() {
        return instance;
    }

    public void pay() {
        System.out.println("成功交钱");
    }

    public void check() {
        System.out.println("验车成功");
    }

    public void getlicense() {
        System.out.println("恭喜获得车牌");
    }
}

子系统三买保险Insurance:包括交钱、填写资料、参保成功等步骤

package com.wangscaler.facade;

/**
 * @author wangscaler
 * @date 2021.06.29 14:39
 */
public class Insurance {
    private static Insurance instance = new Insurance();

    public static Insurance getInstance() {
        return instance;
    }

    public void pay() {
        System.out.println("成功交钱");
    }

    public void write() {
        System.out.println("填写资料");
    }

    public void success() {
        System.out.println("恭喜成功参保");
    }
}

使用外观模式之后,我们无需知道上述三个子系统的详细步骤,因为这些步骤销售Salesmen(外观角色)会帮我们处理

package com.wangscaler.facade;

/**
 * @author wangscaler
 * @date 2021.06.29 14:39
 */
public class Salesmen {
    private PayTaxes payTaxes;
    private License license;
    private Insurance insurance;

    public Salesmen() {
        super();
        this.payTaxes = PayTaxes.getInstance();
        this.license = License.getInstance();
        this.insurance = Insurance.getInstance();
    }

    public void getInvoice() {
        payTaxes.write();
        payTaxes.pay();
        payTaxes.invoice();
    }

    public void geticense() {
        license.pay();
        license.check();
        license.getlicense();
    }

    public void getiInsurance() {
        insurance.pay();
        insurance.write();
        insurance.success();
    }
}

他将这些步骤整合,提供接口供用户使用

main

package com.wangscaler.facade;

/**
 * @author wangscaler
 * @date 2021.06.29 14:39
 */
public class Facade {
    public static void main(String[] args) {
        Salesmen salesmen = new Salesmen();
        salesmen.getInvoice();
        salesmen.geticense();
        salesmen.getiInsurance();
    }
}

源码中的外观模式

Mybatis中的Configuration

public Configuration() {
    this.reflectorFactory = new DefaultReflectorFactory();
    this.objectFactory = new DefaultObjectFactory();
    this.objectWrapperFactory = new DefaultObjectWrapperFactory();
    public MetaObject newMetaObject(Object object) {
        return MetaObject.forObject(object, this.objectFactory, this.objectWrapperFactory, this.reflectorFactory);
    }
      public static MetaObject forObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory, ReflectorFactory reflectorFactory) {
        return object == null ? SystemMetaObject.NULL_META_OBJECT : new MetaObject(object, objectFactory, objectWrapperFactory, reflectorFactory);
    }
}

这个Configuration就是外观角色,对外提供接口newMetaObject,供用户使用。内部却关联了很多其他的子系统。

总结

使用场景:

  1. 对分层结构系统构建时,使用外观模式定义子系统中每层的入口点可以简化子系统之间的依赖关系。
  2. 外观模式可以为一个拥有很多子系统的复杂系统,设计一个简单的接口供外界访问。
  3. 子系统相对独立。

角色:

  • 外观角色:在客户端可以调用外观角色的方法salesmen.getInvoice();,在外观角色的方法内通过多个子系统的去处理payTaxes.write();payTaxes.pay();payTaxes.invoice();
  • 子系统角色:在软件系统中可以有一个或者多个子系统角色(如Insurance、License、PayTaxes)。每一个子系统都可以被客户端直接调用,或者被外观角色调用。

外观模式的本质是:封装交互,简化调用。让复杂的步骤封装起来,让使用者调用更见简单,减少与子系统的交互。

参考资料