python设计模式--门面模式

门面模式

理解结构型设计模式
结构型模式描述如何将对象和类组合成更大的结构
结构型模式是一种能够简化设计工作的模式,因为它能够找出更简单的方法来认识或表示实体之间的关系。在面向对象世界中,结构型模式是一种能够简化设计工作的模式,因为它能够找出更简单的方法来认识或表示实体之间的关系。在面向对象世界中,实体指的是对象或类。
类模式可以通过继承来描述对象,从而提供更有用的程序接口,而对象模式则描述了如何将对象联系起来从而组成更大的对象,结构型模式是类和对象模式的综合体。

结构型设计模式例子:

  • 适配器模式:将一个接口转换为客户希望的另外一个接口。它试图根据客户端的需求来匹配不同类的接口。
  • 桥接模式:该模式将对象的接口与其实现进行解耦,使得两者可以独立工作。
  • 装饰器模式:该模式允许在运行时或以动态方式为对象添加职责。我们可以通过接口给对象添加某些属性。

理解门面设计模式
门面(facade)通常是指建筑物的表面,尤其是最有吸引力的那一面。它也可以一种让人容易误解某人的真实感受或情况的行为或面貌。当人们从建筑物外面经过时,可以欣赏其外部面貌,却不了解建筑物结构的复杂性。这就是门面模式的使用方式。门面在隐藏内部系统复杂性的同时,为客户端提供了一个接口,以便它们可以非常轻松地访问系统。
假设你要到某个商店买东西,但是你是第一次来到这个商店,你对这个商店的布局并不了解。所以一般你都会找店主,因为店主对这个店里面的情况了如执掌。只要你告诉他你要买什么,店主就会把这些商品拿给你。这不就变得简单了吗。顾客不必了解店面里面布局情况,可以通过一个简单的接口(店主)来完成购物。

门面设计模式实际上完成了下列事项:

它为系统中的一组接口提供一个统一的接口,并定义一个高级接口来帮助客户端通过更加简单的方式使用子系统。

门面解决的是,如何使用单个接口对象来表示复杂的子系统。实际上,它并不是封装子系统,而是对底层子系统进行组合。

它促进了实现与多个客户端的解耦。

通过UML图来深入探讨门面模式:

就像你在UML图所看这个模式有三个主要的参与者:

门面: 门面的主要责任是,将一组复杂导致系统封装起来,从而为外部世界提供一个舒适的外观。
系统:这代表一组不同的子系统,使整个系统混杂在一起,难以观察或使用。
客户端:客户端与门面进行交互,这样就可以轻松地与子系统进行通信并完成工作了。不必担心系统复杂性。
1.门面:

它是一个接口,它知道某个请求可以交由哪个子系统进行处理。
它使用组合将客户端的请求委派给相应的子系统使用。
例如:如果客户端正在了解哪些工作已完成,则不需要到各个子系统中去,相反它只需要联系完成工作的接口(门面)就可以了

2.系统:

它实现子系统的功能,同时,系统由一个类表示。理想的情况下系统应该由一组负责不同任务的类来表示。
它处理门面对象的分配的工作,但并不知道门面,而且不引用它。
例如,当客户端向门面请求某项服务时,门面会根据服务的类型来选择该服务的相应子系统。

3.客户端

客户端是实例化门面的类。
为了让子系统完成相应的工作,客户端需要向门面提出请求。

现实世界中实现门面模式(示例)
假设你要在家中举行一场婚礼,并且由你来张罗这一切。这真是一个艰巨的任务。你必须预订一家酒店或场地,与餐饮人员交代酒菜、布置场景,并安排背景音乐。、
你已经自己搞定了一切,如找相关人员谈话、与他们进行协调、敲定价格等,那么现在你就很轻松了。此外,你还可以去找会务经理,让他/她为你处理这些事情。会务经理负责跟各个服务提供商交涉,并为你争取最优惠的价格。
下面我们从门面模式的角度来看待这些事情。
客户端:你需要在婚礼前及时完成所有的准备工作。每一项安排都应该是顶级的,这样客人才会喜欢这些庆祝活动。
门面:会务经理负责与所有相关人员进行交涉,这些人员负责处理食物、花卉装饰等。
子系统:它们代表提供餐饮、酒店管理和花卉装饰等服务的系统。

让我们利用Python开发一个应用程序,实现这个示例。我们首先从客户端开始。记住,你是确保婚姻准备工作和事件顺利的总负责人!
下面是EventManager类的Python代码:

class EventManager(object):
    """
    EventManager(活动经理)
    Hotelier(旅馆经理)
    bookHotel(预定酒店)
    Florist(花商)
    setFlowerRequirements(花需求集)
    Caterer(承办酒席的人)
    setCuisine(美食集)
    Musician(乐师)
    setMusicType(设置音乐类型)
    """
    def __init__(self):
        print('活动经理:让我和大家谈谈\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.setMusicType()

这里已经搞定了门面和客户端,让我们开始深入了解子系统。
所以开发了这个类:
Hotelier类用于预订酒店。它有一个方法,用于检查当天是否有免费的酒店(__isAvailable)
Florist类负责花卉装饰。这个类提供了setFlowerRequirements()方法,用于指定要使用哪些种类的花卉来装饰婚礼。
Caterer类用于跟备办宴席者打交道,并负责安排餐饮。Caterer提供了一个公开的setCuisine()方法,用来指定婚宴的菜肴类型。
Musician类用来安排婚礼的音乐,它使用setMusicType(方法来了解会务的音乐要求。

接下来,先来考察Hotelier对象,其次是Florist对象及其方法。

class Hotelier(object):
    def __init__(self):
        print('为婚礼安排酒店?--')

    def __isAvailable(self):
        print("在指定的日子里,酒店是免费的吗?")
        return True

    def bookHotel(self):
        if self.__isAvailable():
            print("注册预订\n\n")


class Florist(object):
    def __init__(self):
        print("为活动做的花装饰?--")

    def setFlowerRequirements(self):
        print("康乃馨、玫瑰和百合用来装饰\n\n")


class Caterer(object):
    def __init__(self):
        print("活动的食物安排--")

    def setCuisine(self):
        print("中餐和西菜\n\n")


class Musician(object):
    def __init__(self):
        print("婚礼的音乐安排--")

    def setMusicType(self):
        print("将播放爵士乐和古典音乐\n\n")

是,我很聪明,所以将这些事情都委托给了会务经理,不是吗? 让我们来看看You类。在本示例中,创建了一个EventManager类的对象,这样经理就会通过与相关人员进行交涉来筹备婚礼,而你则可以找个地方喝大茶了。

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()

将门面模式和现实世界场景关联起来。

EventManager类是简化接口的门面。
EvementManager通过组合创建子系统的对象,如Hotelier,Caterer等等。

最少知识原则
门面为我们提供了一个统一的系统。它使得子系统更加易于使用。它还将客户端与子系统解耦。门面设计模式背后的设计原理就是最少知识原则。

最少知识原则指导我们减少对象之间的交互,就像你亲近的只有某几个朋友那样。

在设计系统时,对于创建的每个对象,都应该考察与之交互的类的数量, 以及交互的方式。

遵循这个原则,就能够避免创建许多彼此紧密耦合的类的情况。

如果类之间存在大量依赖关系,那么系统就会变得难以维护。如果对系统中的任何一部分进行修改,都可能导致系统的其他部分被无意改变,这意味着系统会退化,这是应该坚决避免的。

迪米特法则(设计准则)
每个单元对系统中其他单元知道的越少越好。
单位应该只与其朋友交流。
单元不应该知道它操作的对象的内部细则。
说明: 最少知识原则和迪米特法则是一致的,都是指向松耦合理论。就像它的名称那样,最少知识原则适用与门面模式的用例,并且原则这个词是指导方针的意思,而不是严格遵守的意思,并且只有在有需求的时候才用。

问答
问.子系统可以有多个门面吗?
答:是的,可以为一组子系统组件实现多个门面。

问.最少知识原则的缺点是什么?
答:门面提供了一个简化的接口供客户端与子系统交互。本着提供简化接口的精神,应用可能会建立多个不必要的接口,这增加了系统的复杂性并且降低了运行时的性能。

问.客户端可以独立访问子系统吗?
答:是的,事实上,由于门面模式提供了简化的接口,这使得客户端不必担心子系统的复杂性。

问.门面是否可以添加自己的功能?
答:门面可以将其“想法”添加到子系统中,例如确保子系统的改进顺序由门面来决定。

posted @ 2021-04-01 16:14  MrSatan  阅读(90)  评论(0编辑  收藏  举报