Python 设计模式(第2版) -- 第二部分(结构型模式)

Python 设计模式(第2版)

然后介绍下结构型设计模式。

下面是一些结构型设计模式的例子:

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

门面模式 – 与门面相适

门面在隐藏内部系统复杂性的同时,为客户端提供了一个接口,以便它们可以非常轻松地访问系统。

假设要在家中举行一场婚礼,必须预订一家酒店或场地,与餐饮人员交代酒菜、布置场景,并安排背景音乐,下面我们从门面模式的角度来看待这些事情。

  • 客户端:需要在婚礼前及时完成所有的准备工作。每一项安排都应该是顶级的,这样客人才会喜欢这些庆祝活动。
  • 门面:会务经理负责与所有相关人员进行交涉,这些人员负责处理食物、花卉装饰等。
  • 子系统:它们代表提供餐饮、酒店管理和花卉装饰等服务的系统。

EventManager 扮演了门面的角色。Hotelier 类用于预订酒店。它有一个方法,用于检查当天是否有免费的酒店(__isAvailable)。Florist 类负责花卉装饰。这个类提供了 setFlowerRequirements() 方法,用于指定要使用哪些种类的花卉来装饰婚礼。Caterer 类用于跟备办宴席者打交道,并负责安排餐饮。Caterer 提供了一个公开的 setCuisine() 法,用来指定婚宴的菜肴类型。 Musician 类用来安排婚礼的音乐,它使用 setMusicType() 方法来了解会务的音乐要求。

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.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("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\n")


class Caterer(object):

    def __init__(self):
        print("Food Arrangements for the Event --")

    def setCuisine(self):
        print("Chinese & Continental Cuisine to be served\n\n")


class Musician(object):

    def __init__(self):
        print("Musical Arrangements for the Marriage --")

    def setMusicType(self):
        print("Jazz and Classical 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.arrange()

    def __del__(self):
        print("You:: Thanks to Event Manager, all preparations done! Phew! ")

you = You()
you.askEventManager()

代理模式 – 控制对象访问

代理通常就是一个介于寻求方和提供方之间的中介系统。寻求方是发出请求的一方,而提供方则是根据请求提供资源的一方。

先通过一个简单的例子来理解该模式。不妨以演员与他的经纪人为例,当制作公司想要找演员拍电影时,他们通常会与经纪人交流,而不是直接跟演员交流。

其中 Actor 是代理。对象 Agent 用于查看 Actor 是否正处于忙碌状态。如果 Actor 正忙,则调用 Actor().occupied() 方法;如果 Actor 不忙,则返回 Actor().available() 方法。

class Actor(object):

    def __init__(self):
        self.isBusy = False

    def occupied(self):
        self.isBusy = True
        print(type(self). __name__ , "is occupied with current movie")

    def available(self):
        self.isBusy = False
        print(type(self). __name__ , "is free for the movie")

    def getStatus(self):
        return self.isBusy

class Agent(object):
    
    def __init__(self):
        self.principal = None

    def work(self):
        self.actor = Actor()
        if self.actor.getStatus():
            self.actor.occupied()
        else:
            self.actor.available()

if __name__ == '__main__':
    r = Agent()
    r.work()

代理设计模式主要完成了以下工作。

  • 它为其他对象提供了一个代理,从而实现了对原始对象的访问控制。
  • 它可以用作一个层或接口,以支持分布式访问。
  • 它通过增加代理,保护真正的组件不受意外的影响。

这里将通过付款用例来展示代理模式的现实应用场景。假设,你在商场溜达,看中了一件漂亮的牛仔衫。你想买这件衬衫,但手里的现金却不够了。这要是在不久以前,你可以去 ATM 取钱,然后来到商场付款。在更早的时候,通常使用的是银行支票,这样你就必须去银行提款,然后再回商场付款。得益于银行业务的发展,后来出现了一种称为借记卡的东西。所以现在,你买东西的时候,只要在商家刷一下借记卡,这笔钱就会划入商家的账户,从而完成支付。

行为由类 You(即客户端)来表示。该类提供了 make_payment() 方法。主题是 Payment 类。它是一个抽象基类,代表一个接口。具有一个 do_pay() 方法,该方法需要借助代理和真实主题来实现。

Bank 类提供了多个方法来处理付款。代理使用 setCard() 方法将借记卡详细信息发送给银行。由 Bank 类(通过 Payment 接口)实现的 do_pay() 方法实际上负责根据可用资金向商家付款。

DebitCard 类是此处的代理。当你想要付款时,它会调用 do_pay() 方法。DebitCard 类充当真实主题(银行)的代理。

from abc import ABCMeta, abstractmethod

class Payment(metaclass=ABCMeta):

    @abstractmethod
    def do_pay(self):
        pass

class Bank(Payment):

    def __init__(self):
        self.card = None
        self.account = None

    def __getAccount(self):
        self.account = self.card # Assume card number is account number
        return self.account

    def __hasFunds(self):
        print("Bank:: Checking if Account", self. __getAccount(), "has enough funds")
        return True

    def setCard(self, card):
        self.card = card

    def do_pay(self):
        if self. __hasFunds():
            print("Bank:: Paying the merchant")
            return True
        else:
            print("Bank:: Sorry, not enough funds! ")
            return False

class DebitCard(Payment):

    def __init__(self):
        self.bank = Bank()

    def do_pay(self):
        card = input("Proxy:: Punch in Card Number: ")
        self.bank.setCard(card)
        return self.bank.do_pay()

class You:

    def __init__(self):
        print("You:: Lets buy the Denim shirt")
        self.debitCard = DebitCard()
        self.isPurchased = None

    def make_payment(self):
        self.isPurchased = self.debitCard.do_pay()

    def __del__(self):
        if self.isPurchased:
            print("You:: Wow! Denim shirt is Mine :-)")
        else:
            print("You:: I should earn more :(")

you = You()
you.make_payment()

代理模式的优点:

  • 代理可以通过缓存笨重的对象或频繁访问的对象来提高应用程序的性能。
  • 代理还提供对于真实主题的访问授权。因此,只有提供合适权限的情况下,这个模式才会接受委派。
  • 远程代理还便于与可用作网络连接和数据库连接的远程服务器进行交互,并可用于监视系统。

门面模式和代理模式的比较

代理模式门面模式
为其他对象提供了代理或占位符,以控制对原始对象的访问为类的大型子系统提供了一个接口
代理对象具有与其目标对象相同的接口,并保存有目标对象的引用实现了子系统之间的通信和依赖性的最小化
充当客户端和被封装的对象之间的中介门面对象提供了单一的简单接口
  • 13
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
《精通Python设计模式 第2》是一本非常优秀的Python设计模式的指南。这本书由Dettori和Gabriele Tomassetti撰写,旨在帮助Python开发者更好地理解和应用设计模式。 这本书共分为11个章节,每个章节都涵盖了一个重要的设计模式或者相关主题。作者在书中详细解释了如何使用Python编写实际的示例代码,并给出了详细的解释和说明。这些示例代码不仅可以帮助读者理解每个设计模式的原理和应用场景,还可以帮助读者提高自己的编程技能。 《精通Python设计模式 第2》的每个章节都以问题和解决方案的形式展示。作者首先介绍了一个真实的问题,在问题背景的基础上,详细解释了设计模式的概念和原理,并给出了使用该设计模式解决问题的示例代码。通过这种方式,读者可以更好地理解设计模式的应用场景和使用方法。 此外,这本书还涵盖了一些高级主题,例如元类和装饰器的应用,以及如何使用设计模式构建可扩展的应用程序。这些高级主题对于有一定Python编程经验的读者来说非常有价值,可以帮助他们进一步提高自己的编程水平。 总之,《精通Python设计模式 第2》是一本非常优秀的Python设计模式的指南,适用于任何想要提高自己Python编程技能的读者。无论是初学者还是有经验的开发者,都能从这本书中学到很多有价值的知识和技巧。我强烈推荐这本书给所有对Python设计模式感兴趣的读者。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值