设计模式-结构型模式(适配器、桥、组合、装饰器、外观、亨元、代理)-程序员宅基地

技术标签: 设计模式  

结构型模式

Structural Pattern

适配器模式

Adapter Pattern

适配器模式(Adapter Pattern):用于将一个类的接口转换成客户端期望的另一种接口。

该模式可让原本由于接口不兼容而不能一起工作的类能协同工作。
如,定义了一个英文翻译类,现需适配成中文翻译类,那么就可以使用适配器模式,在构造方法中构造英文类,再去实现中文方法
class EnglishSpeaker:
    def say_hello(self):
        print("Hello!")


class ChineseTranslator:
    def __init__(self, english_speaker):
        self.english_speaker = english_speaker

    def speak_chinese(self):
        print("你好!")

    def translate(self):
        self.speak_chinese()  # "你好!"
        self.english_speaker.say_hello()  # "Hello!"


english_speaker = EnglishSpeaker()
chinese_translator = ChineseTranslator(english_speaker)
chinese_translator.translate()  # 你好! Hello!

桥模式

Bridge Pattern

桥接模式(Bridge Pattern):将抽象部分和实现部分分离开,以便它们可以独立地变化。
例如,在游戏中有多种武器和角色,我们可以使用桥接模式将武器和角色分离开来,从而可自由地组合它们。
class Weapon:
    def __init__(self, name):
        self.name = name


class Sword(Weapon):
    def attack(self):
        print(f"{self.name} is attacking with sword!")


class Bow(Weapon):
    def attack(self):
        print(f"{self.name} is attacking with bow!")


class Character:
    def __init__(self, name, weapon):
        self.name = name
        self.weapon = weapon

    def attack(self):
        self.weapon.attack()


class Warrior(Character):
    pass


class Mage(Character):
    pass


sword = Sword("Excalibur")
bow = Bow("Robin Hood's Bow")
warrior = Warrior("Arthur", sword)
mage = Mage("Merlin", bow)

warrior.attack()  # Arthur is attacking with sword!
mage.attack()  # Merlin is attacking with bow!

组合模式

Composite Pattern

组合模式(Composite Pattern): 将对象组合成树形结构以表示“整体-部分”层次结构。
如,在一个文件系统中,一个文件夹可以包含多个文件和子文件夹,可用组合模式来表示这个文件系统的结构。
class File:
    def __init__(self, name):
        self.name = name

    def display(self, indent=''):
        print(f"{indent}- {self.name}")


class Folder:
    def __init__(self, name):
        self.name = name
        self.children = []

    def add(self, child):
        self.children.append(child)

    def remove(self, child):
        self.children.remove(child)

    def display(self, indent=''):
        print(f"{indent}+ {self.name}")
        for child in self.children:
            child.display(indent + '  ')


folder1 = Folder("Folder 1")
folder2 = Folder("Folder 2")
file1 = File("File 1")
file2 = File("File 2")
file3 = File("File 3")

folder1.add(file1)
folder1.add(folder2)
folder2.add(file2)
folder2.add(file3)

folder1.display()
'''
+ Folder 1
  - File 1
  + Folder 2
    - File 2
    - File 3
'''

装饰器模式

Decorator Pattern

装饰器模式(Decorator Pattern): 用于动态地给一个对象添加一些新功能,同时不影响对象。

如,一个文本编辑器中,可以来给文本添粗、斜体等样式。
def decorator(func):
    def wrapper(*args, **kwargs):
        print("Before function call")
        result = func(*args, **kwargs)
        print("After function call")
        return result

    return wrapper


@decorator
def some_function():
    print("Function called")


some_function()
'''
Before function call
Function called
After function call
'''

外观模式

Facade Pattern
 

提供一个简单的接口,用于访问底层复杂系统的一些功能。相当于向上屏蔽。

class SubsystemA:
    def operation_a(self):
        pass


class SubsystemB:
    def operation_b(self):
        pass


class Facade:
    def __init__(self):
        self._subsystem_a = SubsystemA()
        self._subsystem_b = SubsystemB()

    def operation(self):
        self._subsystem_a.operation_a()
        self._subsystem_b.operation_b()


facade = Facade()
facade.operation()

亨元模式

Flyweight Pattern

 允许将对象共享以节省内存和提高性能。Python 中,可使用缓存实现享元模式。
class Flyweight:
    def __init__(self, shared_state):
        self._shared_state = shared_state

    def operation(self, unique_state):
        s = f"shared ({self._shared_state}) and unique ({unique_state})"
        print(s)


class FlyweightFactory:
    _flyweights = {}

    def get_flyweight(self, shared_state):
        if shared_state not in self._flyweights:
            self._flyweights[shared_state] = Flyweight(
                shared_state)
        return self._flyweights[shared_state]


factory = FlyweightFactory()
flyweight1 = factory.get_flyweight("state1")
flyweight2 = factory.get_flyweight("state1")
flyweight3 = factory.get_flyweight("state2")
flyweight4 = factory.get_flyweight("state2")

flyweight1.operation("unique1")
flyweight2.operation("unique2")
flyweight3.operation("unique3")
flyweight4.operation("unique4")
"""
shared (state1) and unique (unique1)
shared (state1) and unique (unique2)
shared (state2) and unique (unique3)
shared (state2) and unique (unique4)
"""

代理模式

Proxy Pattern
允许你提供一个代理对象作为另一个对象的接口。控制着对原始对象的访问,并允许创建一些附加行为,例如记录请求日志、缓存数据等。


Subject 是抽象类或接口,定义了 request() 方法的基本契约。RealSubject 实现了 Subject 接口,并实现了具体的 request() 方法。
Proxy 也实现了 Subject 接口,并包含一个 RealSubject 对象的引用。在执行请求之前,Proxy 首先检查用户的访问权限,
然后将请求转发给 RealSubject。通过使用 Proxy 对象,我们可以附加一些额外的功能,例如记录请求日志或缓存数据,而不改变 RealSubject 的代码。
class Subject:
    def request(self):
        pass


class RealSubject(Subject):
    def request(self):
        print("RealSubject: Handling request.")


class Proxy(Subject):
    def __init__(self, real_subject: RealSubject):
        self._real_subject = real_subject

    def request(self):
        if self.check_access():
            self._real_subject.request()

    def check_access(self):
        print("Checking access prior to executing the request.")
        return True


real_subject = RealSubject()
proxy = Proxy(real_subject)

proxy.request()  
# "Checking access prior to executing the request."

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lxd_max/article/details/131051140

智能推荐

oracle 12c 集群安装后的检查_12c查看crs状态-程序员宅基地

文章浏览阅读1.6k次。安装配置gi、安装数据库软件、dbca建库见下:http://blog.csdn.net/kadwf123/article/details/784299611、检查集群节点及状态:[root@rac2 ~]# olsnodes -srac1 Activerac2 Activerac3 Activerac4 Active[root@rac2 ~]_12c查看crs状态

解决jupyter notebook无法找到虚拟环境的问题_jupyter没有pytorch环境-程序员宅基地

文章浏览阅读1.3w次,点赞45次,收藏99次。我个人用的是anaconda3的一个python集成环境,自带jupyter notebook,但在我打开jupyter notebook界面后,却找不到对应的虚拟环境,原来是jupyter notebook只是通用于下载anaconda时自带的环境,其他环境要想使用必须手动下载一些库:1.首先进入到自己创建的虚拟环境(pytorch是虚拟环境的名字)activate pytorch2.在该环境下下载这个库conda install ipykernelconda install nb__jupyter没有pytorch环境

国内安装scoop的保姆教程_scoop-cn-程序员宅基地

文章浏览阅读5.2k次,点赞19次,收藏28次。选择scoop纯属意外,也是无奈,因为电脑用户被锁了管理员权限,所有exe安装程序都无法安装,只可以用绿色软件,最后被我发现scoop,省去了到处下载XXX绿色版的烦恼,当然scoop里需要管理员权限的软件也跟我无缘了(譬如everything)。推荐添加dorado这个bucket镜像,里面很多中文软件,但是部分国外的软件下载地址在github,可能无法下载。以上两个是官方bucket的国内镜像,所有软件建议优先从这里下载。上面可以看到很多bucket以及软件数。如果官网登陆不了可以试一下以下方式。_scoop-cn

Element ui colorpicker在Vue中的使用_vue el-color-picker-程序员宅基地

文章浏览阅读4.5k次,点赞2次,收藏3次。首先要有一个color-picker组件 <el-color-picker v-model="headcolor"></el-color-picker>在data里面data() { return {headcolor: ’ #278add ’ //这里可以选择一个默认的颜色} }然后在你想要改变颜色的地方用v-bind绑定就好了,例如:这里的:sty..._vue el-color-picker

迅为iTOP-4412精英版之烧写内核移植后的镜像_exynos 4412 刷机-程序员宅基地

文章浏览阅读640次。基于芯片日益增长的问题,所以内核开发者们引入了新的方法,就是在内核中只保留函数,而数据则不包含,由用户(应用程序员)自己把数据按照规定的格式编写,并放在约定的地方,为了不占用过多的内存,还要求数据以根精简的方式编写。boot启动时,传参给内核,告诉内核设备树文件和kernel的位置,内核启动时根据地址去找到设备树文件,再利用专用的编译器去反编译dtb文件,将dtb还原成数据结构,以供驱动的函数去调用。firmware是三星的一个固件的设备信息,因为找不到固件,所以内核启动不成功。_exynos 4412 刷机

Linux系统配置jdk_linux配置jdk-程序员宅基地

文章浏览阅读2w次,点赞24次,收藏42次。Linux系统配置jdkLinux学习教程,Linux入门教程(超详细)_linux配置jdk

随便推点

matlab(4):特殊符号的输入_matlab微米怎么输入-程序员宅基地

文章浏览阅读3.3k次,点赞5次,收藏19次。xlabel('\delta');ylabel('AUC');具体符号的对照表参照下图:_matlab微米怎么输入

C语言程序设计-文件(打开与关闭、顺序、二进制读写)-程序员宅基地

文章浏览阅读119次。顺序读写指的是按照文件中数据的顺序进行读取或写入。对于文本文件,可以使用fgets、fputs、fscanf、fprintf等函数进行顺序读写。在C语言中,对文件的操作通常涉及文件的打开、读写以及关闭。文件的打开使用fopen函数,而关闭则使用fclose函数。在C语言中,可以使用fread和fwrite函数进行二进制读写。‍ Biaoge 于2024-03-09 23:51发布 阅读量:7 ️文章类型:【 C语言程序设计 】在C语言中,用于打开文件的函数是____,用于关闭文件的函数是____。

Touchdesigner自学笔记之三_touchdesigner怎么让一个模型跟着鼠标移动-程序员宅基地

文章浏览阅读3.4k次,点赞2次,收藏13次。跟随鼠标移动的粒子以grid(SOP)为partical(SOP)的资源模板,调整后连接【Geo组合+point spirit(MAT)】,在连接【feedback组合】适当调整。影响粒子动态的节点【metaball(SOP)+force(SOP)】添加mouse in(CHOP)鼠标位置到metaball的坐标,实现鼠标影响。..._touchdesigner怎么让一个模型跟着鼠标移动

【附源码】基于java的校园停车场管理系统的设计与实现61m0e9计算机毕设SSM_基于java技术的停车场管理系统实现与设计-程序员宅基地

文章浏览阅读178次。项目运行环境配置:Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot + mybatis + Maven +mysql5.7或8.0+html+css+js等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。_基于java技术的停车场管理系统实现与设计

Android系统播放器MediaPlayer源码分析_android多媒体播放源码分析 时序图-程序员宅基地

文章浏览阅读3.5k次。前言对于MediaPlayer播放器的源码分析内容相对来说比较多,会从Java-&amp;amp;gt;Jni-&amp;amp;gt;C/C++慢慢分析,后面会慢慢更新。另外,博客只作为自己学习记录的一种方式,对于其他的不过多的评论。MediaPlayerDemopublic class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal..._android多媒体播放源码分析 时序图

java 数据结构与算法 ——快速排序法-程序员宅基地

文章浏览阅读2.4k次,点赞41次,收藏13次。java 数据结构与算法 ——快速排序法_快速排序法