前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式——外观模式

设计模式——外观模式

作者头像
Java架构师必看
发布2021-05-14 10:14:58
6090
发布2021-05-14 10:14:58
举报
文章被收录于专栏:Java架构师必看

设计模式——外观模式

强烈推介IDEA2020.2破解激活,IntelliJ IDEA 注册码,2020.2 IDEA 激活码

外观模式(Facade Pattern):隐藏系统的复杂性,并向客户端提供了一个可以访问系统的接口。这种类型的设计属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。这种模式涉及到一个单一的类,该类提供了客户端请求的简化方法和对现有系统方法的委托调用。现实生活中,常常存在很多复杂的例子,例如:去医院看病,可能要去挂号、门诊、化验、开药、取药,让患者家属觉得很复杂,如果有提供接待人员,只让接待人员来处理,就很方便。或者 Java 的三层开发模式等等。软件设计也是如此,当一个系统的功能越来越强,子系统会越来越多,客户对系统的访问也变得越来越复杂。这是如果系统内部发生改变,客户端也要改变,违背了 “开闭原则” 和 “迪米特法则” 所以有必要为多个子系统提供一个统一的接口,从而降低系统的耦合度,这就是外观模式。

一、 外观模式的优点与缺点


外观模式是 “迪米特法则” 的典型应用,优点如下:    1)、降低了子系统与客户端之间的耦合度,使得子系统的变化不会影响调用它的客户类,便于子系统内部维护和扩展。    2)、对客户屏蔽了子系统组件,减少了客户处理的对象数目,并使得子系统使用起来更加容易,降低了复杂性。    3)、降低了大型软件系统中的编译依赖性,简化了系统在不同平台之间的移植过程,因此编译一个子系统不会影响其他子系统,也不会影响外观对象。    4)、子系统也不会影响外观系统。    5)、通过合理的使用外观系统,可以更好的帮我们划分访问层次,当系统需要层次设计时,可以考虑外观模式。    6)、在维护一个遗留的大型系统时,可能这个系统已经变得非常难以维护和扩展,此时可以考虑为新系统开发一个Facad类,来提供遗留系统的比较清晰简单的接口,让新系统与Facade类交互,提高复用性    7)、不能过多的或者不合理的使用外观模式,使用外观模式好,还是直接调用模块好。要以让系统有层次,利于维护为目的。

外观模式的主要缺点如下:    1)、不能很好地限制客户端使用子类系统。    2)、增加了新的子类系统可能需要修改外观类。

二、外观模式结构类图


外观(Facade)模式的结构比较简单,主要是定义了一个高层接口。它包含了对各个子系统的引用,客户端可以通过访问外观类来访问各个子系统的功能。

 外观模式主要包含一下三种角色:    【1】、外观(Facade)角色:为多个子系统对外提供一个共同的接口。    【2】、子系统(Sub System)角色:实现系统的部分功能,客户可以通过外观角色访问它。    【3】、客户(Client)角色:通过一个外观系统访问各个子系统。

三、代码案例分析


【1】定义 CPU 、Hard、Memory 三大子系统之一:通过懒汉式定义了实例化方法(genInstance())

代码语言:javascript
复制
public class Memory {
    private static Memory memory = new Memory();
    public static Memory getInstance() {
        return memory;
    }

    public void open() {
        System.out.println("打开内存");
    }

    public void down() {
        System.out.println("关闭内存");
    }
}

【2】定义外观类:在构造器中通过调用子类的方法,实例化子类对象。

代码语言:javascript
复制
public class Facade {
    private CPU cpu;
    private Memory memory;
    private Hard hard;
    //构造器 初始化子类实例
    public Facade() {
        super();
        this.cpu = CPU.getInstance();
        this.memory = Memory.getInstance();
        this.hard = Hard.getInstance();
    }

    //封装所有打开设备
    public void open() {
        cpu.open();
        hard.open();
        memory.open();
    }
    //封装所有关闭设备
    public void down() {
        cpu.down();
        hard.down();
        memory.down();
    }
}

【3】客户端类:通过调用外观类,实现对子类的调用

代码语言:javascript
复制
public class Client {
    public static void main(String[] args) {
        //外观类
        Facade facade = new Facade();
        //打开电脑
        facade.open();
        //关闭电脑
        facade.down();
    }
}

四、外观模式应用分析


外观模式在 MyBatis 框架中应用的源码分析:

【1】MyBatis 中的 Configuration 去创建 MetaObject 对象使用到外观模式

代码语言:javascript
复制
public class Configuration {
    ......
  //创建子类实例
  protected ReflectorFactory reflectorFactory = new DefaultReflectorFactory();
  protected ObjectFactory objectFactory = new DefaultObjectFactory();
  protected ObjectWrapperFactory objectWrapperFactory = new DefaultObjectWrapperFactory();

  //封装复杂的业务逻辑,返回客户端需要的 MetaObject
  public MetaObject newMetaObject(Object object) {
    this.originalObject = object;
    this.objectFactory = objectFactory;
    this.objectWrapperFactory = objectWrapperFactory;
    this.reflectorFactory = reflectorFactory;

    if (object instanceof ObjectWrapper) {
      this.objectWrapper = (ObjectWrapper) object;
    } else if (objectWrapperFactory.hasWrapperFor(object)) {
      this.objectWrapper = objectWrapperFactory.getWrapperFor(this, object);
    } else if (object instanceof Map) {
      this.objectWrapper = new MapWrapper(this, (Map) object);
    } else if (object instanceof Collection) {
      this.objectWrapper = new CollectionWrapper(this, (Collection) object);
    } else {
      this.objectWrapper = new BeanWrapper(this, object);
    }
  }

【2】上述外观模式应用的类图

所属专题
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、 外观模式的优点与缺点
  • 二、外观模式结构类图
  • 三、代码案例分析
  • 四、外观模式应用分析
    • 所属专题
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档