定义: 每个子系统的外部与其内部的通信必须通过同一个对象进行。即提供一个访问子系统的的接口,只有通过这个接口才能访问子系统的行为。外观模式又成为门面模式,是一种比较简单的设计模式。外观模式是一种结构型设计模式。
涉及到的结构模型:
- 外观角色 : 为众多的子系统提供一个公共的访问接口,该角色没有实际的业务逻辑,只是一个委托类。
- 子系统角色 : 完成系统功能众多类的集合体,而不是指一个类。
下面用一个例子简单阐述外观模式。一个老板手下的产业有搞教育的,有搞娱乐,也有搞艺术的。他觉得自己一个人管理起来太累了就找了个管家帮他去管理这些产业,同时给与了这个管家极大的权利,只有通过这个管家,才能接触到那些产业。这个管家的角色就充当了一个门面角色也就是外观角色,那些娱乐产业,艺术产业等等就组成了一个子系统集合。老板只需要对管家下达任务,管家根据指示通知到下面的人即可,不需要老板亲自指示。子系统角色(各大产业)
// 搞教育的
public class BusinessB {
public void study(){
Log.d("TAG", "学java,学android,学python");
}
}
//搞艺术的
public class BusinessA {
public void relax() {
Log.d("TAG", "唱歌,跳舞,rap");
}
}
//搞娱乐的
public class BusinessC {
public void play() {
Log.d("TAG", "逛街,吃饭,聚会");
}
}
外观角色(管家)
public class BossManager {
private BusinessA a = new BusinessA();
private BusinessB b = new BusinessB();
private BusinessC c = new BusinessC();
public void relax() {
a.relax();
}
public void study() {
b.study();
}
public void play() {
c.play();
}
}
最后老板发号施令:
BossManager manager = new BossManager();
manager.study();
manager.relax();
manager.play();
应用场景:
- 为复杂的模块或者子系统提供外界访问接口;
- 子系统独立,外界对子系统的访问只要黑箱操作;
- 预防风险扩散,控制访问操作;
优点:
- 使用方便,不需要直接管理子系统类,只需要管理一个外观类即可;
- 减少系统的相互依赖。所有系统都只对外观角色依赖,与子系统无关;
- 对于子系统而言提高了灵活性,不管子系统如何变化,只要外观类不变化就不会产生影响;
缺点: - 不符合开闭原则(对修改关闭,对扩展开放),通常修改了子系统,外观类也要相应修改;
小结
外观模式是一种较简单的设计模式。外观模式只分外观角色与子系统角色,而且子系统角色也只是一个功能类集合,外观模式本身并不承担具体逻辑,它的任务就是委托作用,委托子系统角色执行相应的功能。可能会存在疑问:我直接调用子系统角色不是更加简单方便吗?为什么还要去创建一个外观角色的类,而且这个类还没有自己的业务逻辑?这样想是没有错。但要明白一个点是为什么要用设计模式。使用设计模式为了重用代码,让代码更加容易理解,结构更加的清晰明了。试想一下,当这么一个子系统(很多个功能类)要直接使用时,需要创建到多个对象,而且子系统可能还不止于一处使用而是多个地方使用时,这个子系统对象会变得非常重复累赘,代码复用性会很差。而使用了外观模式,将这些子系统类集中于一处管理(外观类),无论在哪里使用都只需要一个对象,就是外观类对象。相比之下,优势就很大了。当然,也不能为了使用设计模式而使用设计模式,有时候效果反而更差,要合理的使用而不是滥用。