首页 > 编程语言 >Python - Structural Design Patterns

Python - Structural Design Patterns

时间:2024-08-16 16:06:46浏览次数:6  
标签:__ obj name Python self Patterns Design class def

• The adapter pattern

The adapter pattern is a structural design pattern that helps us make two incompatible interfaces compatible. What does that really mean? If we have an old component and we want to use it in a new system, or a new component that we want to use in an old system, the two can rarely communicate without requiring any code changes. But changing the code is not always possible, either because we don’t have access to it, or because it is impractical. In such cases, we can write an extra layer that makes all the required modifications for enabling communication between the two interfaces. This layer is called an adapter.

In general, if you want to use an interface that expects function_a(), but you only have function_b(), you can use an adapter to convert (adapt) function_b() to function_a().

class OldPaymentSystem:
    def __init__(self, currency):
        self.currency = currency
def make_payment(self, amount): print(f"[OLD] Pay {amount} {self.currency}") class NewPaymentGateway: def __init__(self, currency): self.currency = currency
def execute_payment(self, amount): print(f"Execute payment of {amount} {self.currency}") class PaymentAdapter: def __init__(self, system): self.system = system
def make_payment(self, amount): self.system.execute_payment(amount) def main(): new_system = NewPaymentGateway("euro") print(new_system) adapter = PaymentAdapter(new_system) adapter.make_payment(100)

Implementing the adapter pattern – adapt several classes into a unified interface

Let’s look at another application to illustrate adaptation: a club’s activities. Our club has two main activities:

• Hire talented artists to perform in the club

• Organize performances and events to entertain its clients

At the core, we have a Club class that represents the club where hired artists perform some evenings. The organize_performance() method is the main action that the club can perform. The code
is as follows:

class Club:
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return f"the club {self.name}"

    def organize_performance(self):
        return "hires an artist to perform"

Most of the time, our club hires a DJ to perform, but our application should make it possible to organize a diversity of performances: by a musician or music band, by a dancer, a one-man or one-woman show, and so on.

Via our research to try and reuse existing code, we find an open source contributed library that brings us two interesting classes: Musician and Dancer. In the Musician class, the main action is performed by the play() method. In the Dancer class, it is performed by the dance() method.

class Musician:
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return f"the musician {self.name}"

    def play(self):
        return "plays music"


class Dancer:
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return f"the dancer {self.name}"

    def dance(self):
        return "does a dance performance"

The code we are writing, to use these two classes from the external library, only knows how to call the organize_performance() method (on the Club class); it has no idea about the play() or dance() methods (on the respective classes).

How can we make the code work without changing the Musician and Dancer classes? 

Adapters to the rescue! We create a generic Adapter class that allows us to adapt a number of objects with different interfaces into one unified interface. The obj argument of the __init__() method is the object that we want to adapt, and adapted_methods is a dictionary containing key/value pairs matching the method the client calls and the method that should be called. The code for that class is as follows:

class Adapter:
    def __init__(self, obj, adapted_methods):
        self.obj = obj
        self.__dict__.update(adapted_methods)

    def __str__(self):
        return str(self.obj)

When dealing with the instances of the different classes, we have two cases:

• The compatible object that belongs to the Club class needs no adaptation. We can treat it as is.

• The incompatible objects need to be adapted first, using the Adapter class.

The result is that the client code can continue using the known organize_performance() method on all objects without the need to be aware of any interface differences. Consider the following main() function code to prove that the design works as expected:

def main():
    objects = [
        Club("Jazz Cafe"),
        Musician("Roy Ayers"),
        Dancer("Shane Sparks"),
    ]
    for obj in objects:         if hasattr(obj, "play") or hasattr(             obj, "dance"         ):             if hasattr(obj, "play"):                 adapted_methods = dict(                     organize_performance=obj.play                 )             elif hasattr(obj, "dance"):                 adapted_methods = dict(                     organize_performance=obj.dance                 )             obj = Adapter(obj, adapted_methods)         print(f"{obj} {obj.organize_event()}")

 

• The decorator pattern

 

• The bridge pattern

 

• The facade pattern

 

• The flyweight pattern

 

• The proxy pattern

 

标签:__,obj,name,Python,self,Patterns,Design,class,def
From: https://www.cnblogs.com/zhangzhihui/p/18363047

相关文章

  • python的基础知识入门
    一.初聊Python为什么要学习Python?在学习Python之前,你不要担心自己没基础或“脑子笨”,我始终认为,只要你想学并为之努力,就能学好,就能用Python去做很多事情。在这个喧嚣的时代,很多技术或概念会不断兴起,我希望你能沉下心来去学习,不要急于求成,一步一个脚印。当你把某个技术学好、......
  • QT设置回调函数给python调用——参数法
    这种方法将回调函数作为python函数参数对象的方法来使用。Qt已经添加了Python库,并且能够正常调用Python的API,可以成功调用Python的代码块,这部分可以参考我另外一篇博客:1.QT相关函数定义1.1创建回调函数例如下面两个函数//实际的回调函数voidprintValue(intvalue){......
  • QT设置回调函数给python调用——内置模块法
    1.QT相关函数定义和 QT设置回调函数给python调用——参数法中的定义相同如下://实际的回调函数voidprintValue(intvalue){qDebug()<<"printValuevalue:"<<value;}intgetValue(intvalue){qDebug()<<"getValuevalue:"<<value;......
  • Python借助Selenium,保留原样式拷贝网站资源
    importurllib3fromseleniumimportwebdriverfrombs4importBeautifulSoupimportosimportrequestsfromurllib.parseimporturljoin,urlparseimportbase64importrefromrequests.adaptersimportHTTPAdapterfromrequests.packages.urllib3.util.retryim......
  • Python魔法应用:自动化日常任务:让Python成为你的私人助理
    自动化日常任务:让Python成为你的私人助理引言自动化文本处理:批量重命名文件、整理数据批量重命名文件整理数据自动化邮件发送:使用smtplib发送邮件自动化网页交互:使用requests库获取网页数据结语引言在日常工作和学习中,我们常常会遇到大量重复且繁琐的任务,这些任务......
  • python 之 pytest框架
    一、pytest单元测试框架1、什么是单元测试,针对软件的最小单位(函数,方法,接口)进行正确性的检查测试。 2、单元测试框架(按语言分)java:junit和testingpython:unittest和pytest 3、单元测试主要是做什么呢?(1)、测试发现:从多个文件里面去找到测试用例(2)、测试执行:按......
  • python蟒蛇绘制
    turtle海龟绘图setup()设置窗体大小及位置setup()不是必须的importturtleturtle.setup(650,350,200,200)turtle.penup()turtle.fd(-250)turtle.pendown()turtle.pensize(25)turtle.pencolor("purple")turtle.seth(-40)foriinrange(4):turtle.circle(40,80)......
  • Python温度的转换
    神清气爽哈哈哈程序代码:#温度的转换TempStr=input("请输入带有符号的温度值:")ifTempStr[-1]in['F','f']:#判断字符转最后一个字符是否为F或fc=(eval(TempStr[0:-1])-32)/1.8#将摄氏度转化为华氏度print("转换后的温度是{:.2f}C".format(c))#eva......
  • 【Python SHA256 摘要算法】
    SHA256是一种广泛使用的密码散列函数,用于生成数据的唯一指纹,即散列值。它属于SHA-2家族,该家族还包括SHA-384和SHA-512算法。SHA256算法在许多领域都有应用,例如:数据完整性验证:用于验证数据在传输或存储过程中是否被篡改。例如,在下载软件时,通常会提供软件的SHA256哈......
  • 使用Python创建省份城市地图选择器
    在这篇博客中,我们将探讨如何使用Python创建一个简单而实用的省份城市地图选择器。这个项目不仅能帮助我们学习Python的基础知识,还能让我们了解如何处理JSON数据和集成网页浏览器到桌面应用程序中。C:\pythoncode\new\geographicgooglemap.py全部代码importwximportwx.......