一、门面模式的概念
听懂了这句话就不用往下看了,说明你会了。
听不懂我觉得也正常,如果用一句话能学会就没人看书了。像我这种笨人,都是学会了一个模式,然后往它的定义上套。
二、什么时候使用门面模式
门面模式,也叫外观模式,从我的理解来说算是设计模式中比较简单的几个模式之一。
它的本质就是封装,以及解耦。使用的场景我大致总结如下:
- 在层次化结构中,可以使用门面模式定义系统中每一层的入口,层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度。这个是最典型的场景,我们的Controller层,都会使用Service层的接口,Service层使用Dao层的接口;
- 调用者(Client)与多个业务接口之间存在很大的依赖性。这是引入门面模式将这些业务接口与调用者解耦,可以提高子系统的独立性和可移植性,比如一个调用者要调用6个接口完成一个业务,那么就可以使用门面模式,把这6个接口封装起来,然后调用者只与门面模式提供的类进行交互;
三、怎么使用门面模式
具体如何使用,通过一个例子来说明。
3.1 反例
加入要实现一个解除汽车上的某个设备的功能,一般的设计是上图中所示,伪代码:
public void unBindDevice(String phoneNumber) {
// 获取用户信息
User user = userService.findUserByPhoneNumber(phoneNumber);
// 获取车辆信息
Vehicle vehicle = vehicleService.findVehicleByUserId(user.getId());
// 获取设备信息
DeviceService device = deviceService.findDeviceByVin(vehicle.getVin());
// 解除绑定
deviceService.unbind(user.getId(), vehicle.getVin(), device.getId());
}
这么做的缺点是,client对象与3个服务模块有依赖关系,当某一个服务发生变化时,都会影响到client。
这种时候就可以使用门面模式。
3.2 正例
使用门面模式,创建一个Facade类,该类提供一个unbind方法,在这个方法内,实现刚才在client中的的操作:
public class Facade {
public void unbind(String phoneNumber) {
// 获取用户信息
User user = userService.findUserByPhoneNumber(phoneNumber);
// 获取车辆信息
Vehicle vehicle = vehicleService.findVehicleByUserId(user.getId());
// 获取设备信息
DeviceService device = deviceService.findDeviceByVin(vehicle.getVin());
// 解除绑定
deviceService.unbind(user.getId(), vehicle.getVin(), device.getId());
}
}
client只与Facade类交互,将复杂的业务细节对client进行隐藏,这就是门面模式的应用。
四、总结
门面模式的优点总结:
- 松散耦合:门面模式接触了客户端与各个业务模块的高耦合,这样在业务发生变化时,客户端不需要进行维护;
- 简单易用:门面模式使得客户端不再需要了解业务内部的实现,也不需要跟众多模块进行交互,只需要跟门面类交互就可以了;
- 更好的划分访问层次:通过合理的使用门面模式,可以帮助我们更好地划分访问的层次。有些方法是对系统外的,有些方法是系统内部使用的。把需要暴露给外部的功能集中到门面中,这样既方便客户端使用,也很好地隐藏了内部的细节。
直白的说,其实主要就是2点:
- 发现调用者完成某业务时,需要与好多个业务接口进行交互,就用门面模式进行封装;
- 在层次结构上,上层调用下层时,下层进行做好封装,不要暴露复杂性,要方便上层使用;
以上就是我对门面模式的一些理解,有不足之处请大家指出,谢谢。