目录
一、什么是外观模式?
概念:我们用举例子的形式来阐述一下什么是外观模式?
在我们生活中,送外卖已经是一件很平常的事,夏天到了,你点了一份蒜蓉大龙虾外加20份羊肉串,店家在接收到你订单的时候开始制作蒜蓉小龙虾与羊肉串,这个美食的制作过程可能很复杂。做好以后,外卖小哥在规定的时间去取你的外卖,然后快马加鞭的给你送过来。最后,你只需要接收外卖小哥给你的外卖,你就可以吃到美滋滋的小龙虾和羊肉串了。
在上面的这个例子中:点外卖的你需要关系如何制作蒜蓉小龙虾吗?需要关心如何烤羊肉串么?需要关心外卖小哥是开车还是骑车给你送外卖么?
这些你统统的不需要关心,你只要负责吃即可。
换到软件开发的过程中,我们同样也可能会接触到一些很复杂的系统,里面子系统之间的调用过程错综复杂,对于每一个不熟悉各子系统的开发人员来说,如何把这些错综复杂的系统调用梳理明白都是一件麻烦而又棘手的事情。
如果这个时候,我们引入一个新的外观类来统一整合这些子模块调用过程,开发人员只需要关注如何对接这个外观类的方法,而无需关注各子系统的调用关系,是不是会让开发变得更加简单容易。类似这种的设计模式就是外观模式,有时候也称为门面模式。它是一种对象结构型模式,也是迪米特法则(最少知道原则)的一种体现。
外观模式的组成特点:
1.外观类:专门整合各子系统的接口,从而实现某些功能。
2.子系统的一组接口等:各子系统有不同的功能实现
总结一句话:实现过程关我毛事,不是该关心的一律不关心,我只调用,最少知道原则。
二、代码示例
1.一组子系统接口方法
/**
* @Description: 模拟子系统1
* @Author: yangshilei
*/
public class SubSystemOne {
public void methodOne(){
System.out.println("子系统1的某个方法");
}
}
/**
* @Description: 模拟子系统2
* @Author: yangshilei
*/
public class SubSystemTwo {
public void methodTwo(){
System.out.println("子系统2的某个方法");
}
}
/**
* @Description: 模拟子系统3
* @Author: yangshilei
*/
public class SubSystemThree {
public void methodThree(){
System.out.println("子系统3的某个方法");
}
}
2.外观类:
/**
* @Description: 外观模式的外观类:用于子系统的方法整合;
* @Author: yangshilei
*/
public class Facade {
private SubSystemOne subSystemOne = new SubSystemOne();
private SubSystemTwo subSystemTwo = new SubSystemTwo();
private SubSystemThree subSystemThree = new SubSystemThree();
/**
* 外观类中具体的整合方法;
*/
public void facadeMethod(){
System.out.println("开始整合子系统的方法!");
subSystemOne.methodOne();
subSystemTwo.methodTwo();
subSystemThree.methodThree();
System.out.println("整合结束");
}
}
3.测试类:
public class FacadeDemo {
public static void main(String[] args) {
Facade facade = new Facade();
facade.facadeMethod();
}
}
执行结果:
****开始整合子系统的方法!****
-------子系统1的某个方法
-------子系统2的某个方法
-------子系统3的某个方法
****整合结束****
以上是一种很简单的外观模式的场景介绍,实际开发中的场景可能比这种情况要复杂的很多。我们可能会使用到继承或者接口等等来提高外观类的可扩展性,来减少子系统的变动对外观类的影响。
思路扩展:除了以上我们写到这种代码形式,我们在实际开发过程中也会用到这种设计模式:以我们常用的spring系列开发框架来说,自定义注解是不是一种不用关心具体实现的模式。
比如:
1.我们需要记录某些接口的特殊业务信息、还有记录参数信息,执行情况,同时需要将这些信息记录到数据库中,供业务重试或者问题分析定位等等,我们就可以尝试使用自定义注解,然后通过AOP切面去实现具体的逻辑操作;
2.比如有些系统为了满足定时任务或者异步消息的模拟登录获取用户信息的功能,也通过自定义注解的形式实现,来把其复杂的登录,角色获取,权限获取等可以整合到一个外观类中。
三、总结
优点:
1.屏蔽了子系统的复杂实现,减少系统间复杂的相互依赖关系
2.松耦合,某个子系统的变化对其它子系统没有影响,子系统的内部实现变化也不会影响外观类;
缺点:
1.外观类限制了客户端直接使用子系统类,属于中间层,如果业务限制太多或者变动频繁,减少了系统的可变性和灵活性。
2.如果设计不合理,子系统的数量变动需要修改外观类,违背了开闭原则。
最后的最后,让我们继续向地中海迈进吧!