四、门面模式-与门面相适 Python3.x
本章研究结构型设计模式:门面模式
本章主题
- 结构型设计模式概要
- 利用UML图理解门面设计模式
- Python3.x实现代码的真实用例
- 门面模式与最少知识原则
1. 理解结构型设计模式
- 结构型模式描述如何将对象和类组合成更大的结构
- 结构型模式是一种能够简化设计工作的模式,因为它能够找出更加简单的方法来认识或表示实体之间的关系。在面向对象世界中,实体指的是对象或类
- 类模式可以通过继承来描述抽象,从而提供更有用的程序接口,而对象模式则描述了如何将对象联系起来从而组成更大的对象。结构型模式是类和对象模式的综合体
2. 理解门面设计模式
门面模式:经过建筑表面,可以欣赏建筑的面貌,却无需了解建筑内部结构的复杂性
门面在隐藏内部系统复杂性的同时,为客户端提供了一个接口,以便它们可以轻松地访问系统
- 门面模式为子系统中的一组接口提供一个统一的接口,并定义一个高级接口来帮助客户端通过简单的方式使用子系统
- 门面所解决问题是,如何用单个接口对象来表示复杂的子系统。实际上,它并不是封装子系统,而是对底层子系统进行组合
- 它促进了实现与多个客户端的解耦
3. UML 类图
我们可以借助UML 类图来深入探讨门面模式
门面模式主要有3个参与者:
- 门面:门面的主要责任是将一组复杂的系统封装起来,从而为外界提供一个舒适的外观
- 系统:这代表一组不同的子系统,使整个系统混杂在一起,难以观察或使用。
- 客户端:客户端与门面进行交互,这样就可以轻松地与子系统进行通信并完成工作了。不必担心系统的复杂性
3.1 门面
- 它是一个接口,它知道某个请求可以交由哪个子系统进行处理
- 它使用组合将客户端的请求委派给相应的子系统对象
3.2 系统
- 它实现子系统的功能,同时,系统由一个类表示。理想情况下,系统应该由一组负责不同的任务的类来表示
- 它处理门面对象分配的工作,但并不知道门面,而且不引用它
3.3 客户端
- 客户端是实例化门面的类
- 为了让子系统完成相应的工作,客户端需要向门面提出请求
4. Python实现门面模式
应用场景:假设你需要举行一场婚礼,并且由你来张罗一切
门面模式的角度分析:
- 客户端:你需要在婚礼前及时完成所有的准备工作。每一项安排都应该顶级的
- 门面:会务经理负责与所有相关人员进行交涉,这些人员负责处理食物、花卉装饰等
- 子系统:它们代表提供餐饮、酒店管理和花卉装饰等服务的系统
# coding: utf-8
# 门面类
class EventManager(object):
def __init__(self):
print("Event Manger:Let me talk to folks\n")
def arrage(self):
self.hotelier = Hotelier() # 酒店类
self.hotelier.bookHotel() # 预定酒店
self.florist = Florist() # 鲜花类
self.florist.setFlowerRequirements() # 指定哪种花来装饰婚礼
self.caterer = Caterer() # 宴席承办人
self.caterer.setCuisine() # 指定酒店的饭菜类型
self.musician = Musician() # 婚礼音乐类
self.musician.setMusicType() # 音乐要求
class Hotelier(object):
def __init__(self):
print("Arranging the Hotel for Marriage ---")
def __isAvailable(self):
print("Is the Hotel free for the event on given day? ")
return True
def bookHotel(self):
if self.__isAvailable:
print("Registed the Booking\n\n")
class Florist(object):
def __init__(self):
print("Flower Descrations for the Event ---")
def setFlowerRequirements(self):
print("choose Roses, Carnations and Lilies that day\n\n")
class Caterer(object):
def __init__(self):
print("Food Arrangments for the Event ---")
def setCuisine(self):
print("Chinese & Continental Cuisine to be serverd\n\n")
class Musician(object):
def __init(self):
print("Musicial Arrangments for the Merriage --")
def setMusicType(self):
print("Jazz & Classcial will be played\n\n")
class You(object):
def __init__(self):
print("You:: Whoa! Marriage Arrangements ??!!")
def askEventManager(self):
print("You:: Let's Contact the Event Manager\n\n")
em = EventManager()
em.arrage()
def __del__(self):
print("You:: Thanks to Event Manager, all preparations done!")
you = You()
you.askEventManager()
运行结果:
You:: Whoa! Marriage Arrangements ??!!
You:: Let’s Contact the Event Manager
Event Manger:Let me talk to folks
Arranging the Hotel for Marriage —
Registed the Booking
Flower Descrations for the Event —
choose Roses, Carnations and Lilies that day
Food Arrangments for the Event —
Chinese & Continental Cuisine to be serverd
Jazz & Classcial will be played
You:: Thanks to Event Manager, all preparations done!
我们通过以下方式将门面模式与真实世界场景相关联
- EventManager 类是简化接口的门面
- EventManager 通过组合创建子系统的对象,如 Hotelier, Caterer,等等
5. 最少知识原则
门面模式背后的设计原理就是最少知识原则
最少知识原则:指导我们减少对象之间的交互
- 在设计系统时,对于创建的每个对象,都应该考察与之交互的类的数量,以及交互的方式
- 遵循这个原则,就能够避免创建许多彼此紧密耦合的类的情况
- 如果类之间存在大量的依赖关系,那么系统就会变得难以维护。如果对系统中的任务一部分进行修改,都可能导致系统的其他部分被无意改变,这意味着系统会退化,是应该坚决避免的
6. 常见问答
- 迪米特法则是什么,它与门面模式有何关联?
迪米特法则是一个设计准则
- 每个单元对系统中的其他单元知道的越少越好
- 单位应该只与其朋友交流
- 单元不应该知道它操作的对象的内部细节
最少知识原则和迪米特法则是一致的,都是指向松耦合理论。
-
子系统可以有多个门面吗?
是的,可以一组子系统组件实现多个门面 -
最少知识原则的缺点是什么?
门面提供了一个简化的接口供客户端与子系统交互。本着提供简化接口的精神,应用可能会建立多个不必要的接口,这增加了系统的负责性并且降低了运行时的性能 -
客户端可以独立访问子系统吗?
是的,实际上,由于门面模式提供了简化的接口,这使得客户端不必担心系统的复杂性 -
门面是否可以添加自己的功能?
门面可以将其“想法”添加到子系统中,例如确保子系统的改进顺序由门面来决定
7. 小结
- 结构型设计模式简介
- 门面的基础知识,以及如何将其高效地应用于软件架构中
- 如何利用门面模式创建一个简单的接口来供客户使用
- 由于门面并没有对子系统进行封装,因此即使不通过门面,客户端也可以自由访问子系统
- UML 类图,Python3.x实现门面模式的示例代码
- 最少知识原则,以及该原则是如何指导门面设计模式的
- 常见问题解答