文章目录
- 4.1 结构型设计模式
- 4.1.1 简介
- 4.1.2 常见的几种结构型设计模式
- 4.2 理解门面设计模式
- 4.2.1 门面设计模式概述
- 4.2.2 门面设计模式的作用
- 4.3 UML类图
- 4.3.1 门面
- 4.3.2 系统
- 4.3.3 客户端
- 4.4 门面模式的代码实现
- 4.4.1 场景:
- 4.4.2 python实现
- 4.5 原理:最少知识原则
- 4.6 门面模式的优缺点
- 4.6.1 门面模式优点
- 4.6.2 门面模式缺点
门面模式属于结构型设计模式的一种,下面我们先了解一下结构型设计模式:
4.1 结构型设计模式
4.1.1 简介
● 结构型模式描述如何将对象和类组合成更大的结构。
● 结构型模式是一种能够简化设计工作的模式,因为它能够找出更简单的方法来认识或表示实体之间的关系。
● 在面向对象世界中,实体指的是对象或类。
● 类模式可以通过继承来描述抽象,从而提供更有用的程序接口,而对象模式则描述了如何将对象联系起来从而组合成更大的对象。结构型模式是类和对象模式的综合体。
4.1.2 常见的几种结构型设计模式
下面给出结构型设计模式的几个例子。你会注意到,它们都是通过对象或类之间的交互来实现更高级的设计或架构目标的。
● 适配器模式:将一个接口转换成客户希望的另外一个接口。它试图根据客户端的需求来匹配不同类的接口。
● 桥接模式:该模式将对象的接口与其实现进行解耦,使得两者可以独立工作。
● 装饰器模式:该模式允许在运行时或以动态方式为对象添加职责。我们可以通过接口给对象添加某些属性。
4.2 理解门面设计模式
4.2.1 门面设计模式概述
门面(facade)在隐藏内部系统复杂性的同时,为客户端提供了一个接口,以便它们可以非常轻松地访问系统。下面,我们以店主为例进行介绍。
现在,假设你要到某个商店去买东西,但是你对这个商店的布局并不清楚。通常情况下,你会去找店主,因为店主对整个商店都很清楚。只要你告诉他/她要买什么,店主就会把这些商品拿给你。这不是很容易吗?顾客不必了解店面的情况,可以通过一个简单的接口来完成购物,这里的接口就是店主。
4.2.2 门面设计模式的作用
门面设计模式实际上完成了下列事项
● 它为子系统中的一组接口提供一个统一的接口,并定义一个高级接口来帮助客户端通过更加简单的方式使用子系统。
● 门面所解决问题是,如何用单个接口对象来表示复杂的子系统。实际上,它并不是封装子系统,而是对底层子系统进行组合。
● 它促进了实现与多个客户端的解耦。
4.3 UML类图
就像你在UML图中看到的那样,这个模式有3个主要的参与者:
● 门面:门面的主要责任是,将一组复杂导致系统封装起来,从而为外部世界提供一个舒适的外观。
● 系统:这代表一组不同的子系统,使整个系统混杂在一起,难以观察或使用
● 客户端:客户端与门面进行交互,这样就可以轻松地与子系统进行通信并完成工作了。不必担心系统的复杂性。
下面,我们将会从数据结构的角度进一步介绍这3个主要参与者。
4.3.1 门面
以下几点可以帮助我们更好地理解门面
● ·它是一个接口,它知道某个请求可以交由哪个子系统进行处理。
● 它使用组合将客户端的请求委派给相应的子系统对象。例如,如果客户端正在了解哪些工作已完成,则不需要到各个子系统去,相反,它只需要联系完成工作的接口(门面)就可以了
4.3.2 系统
在门面的世界里,系统就是执行以下操作的实体
● 它实现子系统的功能,同时,系统由一个类表示。理想情况下,系统应该由一组负责不同任务的类来表示。
● 它处理门面对象分配的工作,但并不知道门面,而且不引用它。
例如,当客户端向门面请求某项服务时,门面会根据服务的类型来选择提供该服务的相应子系统。
4.3.3 客户端
以下是我们对客户端的描述
● 客户端是实例化门面的类
● 为了让子系统完成相应的工作,客户端需要向门面提出请求。
4.4 门面模式的代码实现
4.4.1 场景:
假设你要在家中举行一场婚礼,并且由你来张罗这一切。这真是一个艰巨的任务。你必须预订一家酒店或场地,与餐饮人员交代酒菜、布置场景,并安排背景音乐。
之前,你可能需要自己搞定一切,例如找相关人员谈话、与他们进行协调、敲定价格等。那么现在你就很轻松了,你可以直接去找会务经理,让他为你处理这些事情。会务经理负责跟各个服务提供商交涉,并为你争取最优惠的价格。
4.4.2 python实现
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# 门面类 会务经理:通过组合创建子系统的对象
class EventManager(object):
def __init__(self):
print("Event Manager:: Let me talk to the folks\n")
def arrange(self):
self.hotelier = Hotelier()
self.hotelier.bookHotel() # 定酒店
self.florist = Florist()
self.florist.setFlowerRequirements() # 定花
self.caterer = Caterer()
self.caterer.setCuisine() # 准备宴席
self.musician = Musician()
self.musician.setCuisine()
# 门下调用的子系统1
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("Registered the Booking\n\n")
# 门下调用的子系统
class Florist(object):
def __init__(self):
print("Flower Decorations for the Event? --")
def setFlowerRequirements(self):
print("Carnations,Roses and Lilies would be used for Decorations \n")
# 门下调用的子系统
class Caterer(object):
def __init__(self):
print("Food Arrangements for the Event --")
def setCuisine(self):
print("Chinese & Continental Cuisine to be served\nin")
# 门下调用的子系统
class Musician(object):
def __init__(self):
print("Musical Arrangements for the Marriage --")
def setCuisine(self):
print("Chinese & Continental Cuisine to be served\n\n")
# 客户端类,调用门面的一方
class You(object):
def __init__(self):
print("开始筹备一场婚礼!!!")
def askEventManager(self):
print("联系门面类,让其来组织各项事务\n\n")
em = EventManager()
em.arrange()
def __del__(self):
print("筹备结束!!!")
# 调用
you = You()
you.askEventManager()
4.5 原理:最少知识原则
门面模式背后的设计原理就是最少知识原则,它指导我们设计系统时要减少对象之间的交互,就像跟你亲近的只有某几个朋友那样。实际上,它意味着:
● 在设计系统时,对于创建的每个对象,都应该考察与之交互的类的数量,以及交互的方式;
● 遵循这个原则,就能够避免创建许多彼此紧密耦合的类的情况;
● 如果类之间存在大量依赖关系,那么系统就会变得难以维护。如果对系统中的任何部分进行修改,都可能导致系统的其他部分被无意改变,这意味着系统会退化是应该坚决避免的。
4.6 门面模式的优缺点
4.6.1 门面模式优点
由于门面模式提供了简化的接口,这使得客户端不必担心子系统的复杂性;
4.6.2 门面模式缺点
门面提供了一个简化的接口供客户端与子系统交互。本着提供简化接口的精神,应用可能会建立多个不必要的接口,这就增加了系统的复杂性并且降低了运行时的性能。