设计模式--外观模式

一、举个栗子
小明每天回家都会先打开灯,空气净化器,电热水器烧上水,放上音乐,如果天气热的话,再打开空调。
写成代码

lights.on();//打开灯
airCleaner.on();//打开空气净化器
airCleaner.setMode(auto);//设置自动模式
waterHeater.on();//打开电热水器
waterHeater.setTemperature(40);//水温40度
player.on();//打开音响
play.play(music);//放上音乐
...
//涉及到太多类了!!!

出门的时候,还得反向操作把它们都关掉。
如果升级了系统,还得重新学习另一套操作流程。
那么就使用外观模式来改造成智能家居吧。

二、设计思路
1、创建一个名为HomeFacade新类,对外暴露几个简单的方法,如open()
2、这个新类把灯,音响,空调等视为子系统,让open()去调用他们
3、客户端去调用HomeFacade所提供的方法,而无须再分步骤调用子系统,就可以完成所有操作


设计模式--外观模式_第1张图片
image.png

外观只提供更直接的操作,并没有将原来的子系统隔离起来,还是可以调用原来的子系统的。

具体实现:

public class HomeFacade {
  //所用到的子系统组件
  musicPlayer player;
  Light light;
  ...
  //将子系统的每个组件传入构造器,并赋值给实例变量
  public HomeFacade(musicPlayer player, Light light, ...) {
    this.player = player;
    this.light = light;
    ...
  }
  public void open() {
    lights.on();//打开灯
    airCleaner.on();//打开空气净化器
    airCleaner.setMode(auto);//设置自动模式
    waterHeater.on();//打开电热水器
    waterHeater.setTemperature(40);//水温40度
    player.on();//打开音响
    play.play(music);//放上音乐
  }
  public void endMovie() {
    lights.off();
    airCleaner.off();
    waterHeater.();
    ...
  }
}

//进家门
public class HomeTestDrive {
  public static void main(String[] args) {
    HomeFacade home = new HomeFacade(player, light, ...);
    //使用简化的接口,打开各种电器,然后关闭各种电器
    home.open();
    home.close();
  }
}

三、外观模式
1、定义:
外观模式提供了一个统一的接口,用来访问子系统中的一群接口,外观定义了一个高层接口,让子系统更容易使用。
外观模式封装了子系统的操作,暴露一个统一的接口让用户使用,避免了用户需要与多个子系统进行交互,降低了系统的耦合度、复杂度。如果没有外观模式的封装,那么用户就必须知道各个子系统的相关细节,子系统之间的交互必然造成纠缠不清的关系,影响系统的稳定性、复杂度。
2、类图


设计模式--外观模式_第2张图片
image.png

Tips:
最少知识原则:要减少对象间的交互,只和密友交谈。也就是说,不要让太多的类耦合在一起,避免修改系统中的一部分,会影响其他部分,如果许多类之间相互依赖,那这个系统的维护成本就会很高,也不容易被他人了解。

3、与装饰者模式,适配器模式的区别
装饰者模式是将一个对象包装起来,增加新的行为和责任


设计模式--外观模式_第3张图片
image.png

适配器模式是现有类的接口不符合需要,必须转换成不同的接口,(将一个对象包装起来改变接口)以符合客户的期望
外观模式可以简化并统一一个很大很复杂的接口,(将对象“包装”起来简化接口)将用户从组件的子系统中解耦


设计模式--外观模式_第4张图片
image.png

四、外观模式在Android中的应用
在Android中,Context是最重要的一个类型。它封装了很多重要的操作,比如startActivity()、sendBroadcast()等,这些功能内部的实现非常复杂,但是我们无需关心它内部实现了什么,我们只关心它帮我们启动Activity,帮我们发送了一条广播,绑定了Activity等等就够了。
Context是一个抽象类,它只是定义了抽象接口,真正的实现在ContextImpl类中,在ContextImpl内部有很多xxxManager类的对象,也就是前面所说的各种子系统。
设计模式--外观模式_第5张图片
image.png

你可能感兴趣的:(设计模式--外观模式)