结构型模式 (Python版)

代理模式

from abc import ABC, abstractmethod


# 买的行为(抽象类)
class Buy(ABC):

    @abstractmethod
    def buy_ticket(self):
        pass


# 男人(具体类)
class Man(Buy):

    # 男人买票
    def buy_ticket(self):
        print("Man 买票成功!")


# 女人(具体类)
class Woman(Buy):

    # 女人买票
    def buy_ticket(self):
        print("Woman 买票成功!")


# 代理(抽象类)
class Agency(ABC):

    def __init__(self, people: Buy):
        self._people = people  # 用来保存要代理的对象(男人或女人)

    @abstractmethod
    def click_to_buy_ticket(self):
        pass


# 美团代理(具体类)
class MeiTuan(Agency):

    def click_to_buy_ticket(self):
        print("正在通过美团进行买票...")
        self._people.buy_ticket()


# 携程代理(具体类)
class XieCheng(Agency):

    def click_to_buy_ticket(self):
        print("正在通过携程进行买票...")
        self._people.buy_ticket()


if __name__ == '__main__':
    man = Man()  # 实例化一个男人
    woman = Woman()  # 实例化一个女人

    man.buy_ticket()  # 男人直接自己买票
    woman.buy_ticket()  # 女人直接自己买票

    meituan = MeiTuan(man)  # 男人使用(打开)了美团
    meituan.click_to_buy_ticket()  # 通过美团进行买票

    xiecheng = XieCheng(woman)  # 女人使用(打开)了携程
    xiecheng.click_to_buy_ticket()  # 通过携程进行买票

装饰者模式

from abc import ABC, abstractmethod


# 人物(抽象类)
class People(ABC):

    def __init__(self):
        self._wearingState = ""  # 记录人物的穿着状态

    @abstractmethod
    def show(self):  # 展示人物的穿着状态
        pass


# 女孩(具体类)
class Girl(People):

    def __init__(self):
        super().__init__()
        self._wearing_state = "女孩穿着,长裤睡衣,长袖睡衣"

    def show(self):
        print(self._wearing_state)


# 男孩(具体类)
class Boy(People):

    def __init__(self):
        super().__init__()
        self._wearing_state = "男孩穿着,短裤睡衣,短袖睡衣"

    def show(self):
        print(self._wearing_state)


# 换装(抽象类)
class ChangeClothes(ABC):

    def __init__(self, people: People):
        self._people = people  # 维护一个要进行换装的对象(男孩或女孩)
        self._changed_state = ""  # 记录换装后的穿着状态

    # 展示最新的穿着状态
    @abstractmethod
    def show(self):
        pass


# 换成校服
class ChangeIntoSchoolUniform(ChangeClothes):

    def __init__(self, people: People):
        super().__init__(people)
        self._changed_state = "但是最后换成了校服"

    # 展示最新的穿着状态
    def show(self):
        self._people.show()
        print(self._changed_state)


# 换成运动装
class ChangeIntoSportswear(ChangeClothes):

    def __init__(self, people: People):
        super().__init__(people)
        self._changed_state = "但是最后换成了运动装"

    # 展示最新的穿着状态
    def show(self):
        self._people.show()
        print(self._changed_state)


if __name__ == '__main__':
    # 实例化一个男生,并展示他的穿着状态
    boy = Boy()
    boy.show()

    # 实例化一个女生,并展示她的穿着状态
    girl = Girl()
    girl.show()

    # -------------------- 装饰 - -------------------

    # 让男生穿上运动装,并再次展示他的穿着状态
    boy = ChangeIntoSportswear(boy)
    boy.show()

    # 让女生穿上校服,并再次展示她的穿着状态
    girl = ChangeIntoSportswear(girl)
    girl.show()

适配器模式

对象适配器

"""
    电源插座案例:三插头和两插头的适配
    用户本身只有三插头
    用户现在需要将三插头转换为两插头
"""

from abc import ABC, abstractmethod


# 三插头(具体类)
class ThreePlug:

    # 让三插头进行充电
    def three_plug_charge(self):
        print("开始充电...")


# 两插头形状(抽象类)
class TwoPlugShape(ABC):

    # 让两插头进行充电(抽象)
    @abstractmethod
    def two_plug_charge(self):
        pass


# 两插头(具体类)
class TwoPlug(TwoPlugShape):

    # 让两插头进行充电(实现)
    def two_plug_charge(self):
        print("开始充电...")


# 插头转换器(本质是一个两插头,里面维护了一个三插头对象)
class PlugConverter(TwoPlugShape):

    def __init__(self, obj: ThreePlug):
        self._three_plug = obj  # 保存(维护)一个三插头对象

    # 让两插头进行充电(实现)
    def two_plug_charge(self):
        print("温馨提示:您正在使用插头转换器")  # 插头转换器新增的提示功能
        self._three_plug.three_plug_charge()  # 保持使用三插头原本的充电功能


if __name__ == '__main__':
    # 实例化一个三插头
    three_plug = ThreePlug()

    # 先尝试一下直接充电
    three_plug.three_plug_charge()

    # 在三插头上面安装一个转换器,将其转成两插头(即:实例化一个插头转换器)
    two_plug = PlugConverter(three_plug)

    # 对它进行充电
    two_plug.two_plug_charge()

类适配器

"""
    电源插座案例:三插头和两插头的适配
    用户本身只有三插头
    用户现在需要将三插头转换为两插头
"""

from abc import ABC, abstractmethod


# 三插头(具体类)
class ThreePlug:

    # 让三插头进行充电
    def three_plug_charge(self):
        print("开始充电...")


# 两插头形状(抽象类)
class TwoPlugShape(ABC):

    # 让两插头进行充电(抽象)
    @abstractmethod
    def two_plug_charge(self):
        pass


# 两插头(具体类)
class TwoPlug(TwoPlugShape):

    # 让两插头进行充电(实现)
    def two_plug_charge(self):
        print("开始充电...")


# 插头转换器(通过同时继承两插头和三插头实现转换)
class PlugConverter(TwoPlugShape, ThreePlug):

    # 让两插头进行充电(实现)
    def two_plug_charge(self):
        print("温馨提示:您正在使用插头转换器")  # 插头转换器新增的提示功能
        self.three_plug_charge()  # 保持使用三插头原本的充电功能


if __name__ == '__main__':
    # 实例化一个三插头
    three_plug = ThreePlug()

    # 先尝试一下直接充电
    three_plug.three_plug_charge()

    # 实例化一个插头转换器,它内部自带三插头,但是对外显示两插头
    two_plug = PlugConverter()

    # 对它进行充电
    two_plug.two_plug_charge()

桥接模式

"""
    案例:生成图案
    要求:颜色类和形状类进行搭配,生成图案:"红色圆形"、"蓝色圆形"、"红色矩形"、"蓝色矩形"
        1. 颜色有两个:红色、蓝色
        2. 形状有两个:圆形、矩形
"""

from abc import ABC, abstractmethod


# 颜色(抽象类)
class Color(ABC):

    @abstractmethod
    def fill_color(self):
        pass


# 红色(具体类)
class Red(Color):

    def fill_color(self):
        print("填充了红色")


# 蓝色(具体类)
class Blue(Color):

    def fill_color(self):
        print("填充了蓝色")


# 形状(抽象类)
class Shape(ABC):

    def __init__(self):
        self._color = None  # 用来存放(维护)一个颜色对象

    def set_color(self, color: Color):  # 设置颜色对象
        self._color = color

    @abstractmethod
    def _draw_shape(self):  # 画出形状
        pass

    def generate(self):  # 生成图案(形状+颜色)
        self._draw_shape()
        self._color.fill_color()


# 圆形形状(具体类)
class Circle(Shape):

    def _draw_shape(self):
        print("画出了圆形 ", end="")


# 矩形形状(具体类)
class Rectangle(Shape):

    def _draw_shape(self):
        print("画出了矩形 ", end="")


if __name__ == '__main__':
    # 创建对象
    red = Red()  # 创建一个红色对象
    blue = Blue()  # 创建一个蓝色对象
    circle = Circle()  # 创建一个圆形对象
    rectangle = Rectangle()  # 创建一个矩形对象

    # 生成图案
    # 1. 红色圆形
    circle.set_color(red)
    circle.generate()

    # 2. 蓝色圆形
    circle.set_color(blue)
    circle.generate()

    # 3. 红色矩形
    rectangle.set_color(red)
    rectangle.generate()

    # 4. 蓝色矩形
    rectangle.set_color(blue)
    rectangle.generate()

外观模式

"""
    编译过程是比较复杂的,通常包含以下内容:
        - 编译器在后台进行语法分析
        - 生成中间代码	(预处理)
        - 生成汇编代码	(编译)
        - 生成机器码		(汇编)
        - 生成可执行程序	(链接)

    虽然如此,现实中 IDE(集成开发环境) 通常能够给我们提供一键编译的方法,方便了我们的开发
    下面,我们将模拟这个过程
"""

from abc import ABC, abstractmethod


# 语法分析
class SyntaxAnalyzer:

    def syntax_parser(self):
        print("分析语法中...")


# 中间代码
class MidCode:

    def generate_middle_code(self):
        print("生成中间代码中...")


# 汇编代码
class AssemblyCode:

    def generate_assembly_code(self):
        print("生成汇编代码中...")


# 机器码
class BinaryCode:

    def generate_binary_code(self):
        print("生成机器码中...")


# 链接
class Link:

    def generate_program(self):
        print("生成可执行程序中...")


# IDE(继承开发环境)
class IDE:

    # 编译
    def compile(self):
        # 创建对象
        sa = SyntaxAnalyzer()
        mc = MidCode()
        ac = AssemblyCode()
        bc = BinaryCode()
        lk = Link()

        sa.syntax_parser()
        mc.generate_middle_code()
        ac.generate_assembly_code()
        bc.generate_binary_code()
        lk.generate_program()

        print("程序运行中...")


if __name__ == '__main__':
    python_IDE = IDE()
    python_IDE.compile()  # 一键编译
    

享元模式

"""
    享元模式(Flyweight Mode)
    案例:用户访问多个相似的网站,这些相似的网站之间,有共享的部分,也有自己独有的部分
"""

from abc import ABC, abstractmethod


# 用户类
class User:

    def __init__(self, username):
        self._username = username

    # 向外提供访问用户名字的接口
    @property
    def name(self):
        return self._username


# 网站类(抽象)
class AbstractWebsite(ABC):

    @abstractmethod
    def show_page(self, user: User):  # 网站为用户提供了展示页面的功能
        pass


# 网站类(具体)
class Website(AbstractWebsite):

    def __init__(self, web_name: str):
        self._web_name = web_name

    def show_page(self, user: User):
        print(f"网站:{self._web_name} 正在为用户:{user.name} 展示页面")


# 网站工厂
class WebsiteFactory:

    def __init__(self):
        self._website_dict = {}  # 网站字典  (key: value)<==>(web名字: web对象)

    # 生成网站
    def generate_website(self, web_name: str):
        # 判断网站字典中是否存在名字为 web_name 的网站,如果没有就创建一个
        if web_name not in self._website_dict:
            self._website_dict[web_name] = Website(web_name)
        return self._website_dict.get(web_name)

    # 查看网站数量
    def check_website_count(self):
        return len(self._website_dict)


if __name__ == '__main__':
    # 实例化一个网站工厂
    web_factory = WebsiteFactory()

    # 让工厂生产出三个网站
    web_1 = web_factory.generate_website("华为官网")
    web_2 = web_factory.generate_website("小米官网")
    web_3 = web_factory.generate_website("腾讯官网")

    # 实例化三个用户
    user_1 = User("小明")
    user_2 = User("小帅")
    user_3 = User("小美")

    # 让三个网站,展示页面给三个用户看
    web_1.show_page(user_1)
    web_2.show_page(user_1)
    web_3.show_page(user_1)
    print("--------------")

    web_1.show_page(user_2)
    web_2.show_page(user_2)
    web_3.show_page(user_2)
    print("--------------")

    web_1.show_page(user_3)
    web_2.show_page(user_3)
    web_3.show_page(user_3)
    print("--------------")

组合模式

from abc import ABC, abstractmethod

"""
    案例:通过组合模式,模仿并实现一个简单的目录文件系统
"""


# 容器(抽象类)
class Container(ABC):

    @abstractmethod
    def get_name(self):  # 获取名字
        pass

    @abstractmethod
    def add(self, obj):  # 添加内容
        pass

    @abstractmethod
    def remove(self, obj):  # 移除内容
        pass

    @abstractmethod
    def get_children(self):  # 获取所有的子对象
        pass


# 目录(具体类)
class Directory(Container):

    def __init__(self, directory_name: str):
        self._directory_name = directory_name
        self._children_list = []  # 孩子列表,用来存放所有的子对象(目录的子对象可以是文件对象,也可以是目录对象)

    def get_name(self):  # 获取目录的名字
        return self._directory_name

    def add(self, obj):  # 向目录里面添加子对象
        self._children_list.append(obj)

    def remove(self, obj):  # 移除目录里面的子对象
        self._children_list.remove(obj)

    def get_children(self):  # 获取目录下的所有的子对象
        return self._children_list


# 文件(具体类)
class File(Container):

    def __init__(self, file_name: str):
        self._file_name = file_name
        self._children_list = []  # 孩子列表,用来存放所有的子对象(虽然文件没有子对象,但是为了格式与上面的统一,就保持风格写了这些代码,即:这些代码没有具体的现实意义)

    def get_name(self):  # 获取文件的名字
        return self._file_name

    def add(self, obj):  # 向文件里面添加子对象(为了保持格式统一,没有具体的现实意义)
        pass

    def remove(self, obj):  # 移除文件里面的子对象(为了保持格式统一,没有具体的现实意义)
        pass

    def get_children(self):  # 获取文件下的所有的子对象(为了保持格式统一,没有具体的现实意义)
        return self._children_list


# 目录节点树(用来显示目录的内容与结构)
def show_tree(obj: Container, width: int):
    # ------- 展示当前目录 -------
    i = 0
    while i < width:
        print("---", end="")
        i += 1
    print(obj.get_name())  # 展示当前对象的名称
    # ------- 展示当前目录 -------

    # ------- 展示当前目录下的子对象 -------
    children = obj.get_children()  # 获取当前目录所有的孩子对象,children 本质是列表
    if not children:  # 不存在子对象,直接返回
        return None
    for obj in children:  # 将对象逐个遍历出来
        show_tree(obj, width + 1)
    # ------- 展示当前目录下的子对象 -------


if __name__ == '__main__':
    # 实例化一个目录,作为根目录
    root_directory = Directory("C:")

    # 实例化一个目录,作为子目录,并将其添加到根目录中
    child_directory = Directory("User")
    root_directory.add(child_directory)

    # 实例化四个文件,将前面两个文件添加到根目录中,后面两个文件添加到子目录中
    file_1 = File("a.txt")
    file_2 = File("b.txt")
    file_3 = File("c.txt")
    file_4 = File("d.txt")

    root_directory.add(file_1)
    root_directory.add(file_2)
    child_directory.add(file_3)
    child_directory.add(file_4)

    # 查看根目录的"目录节点树"
    show_tree(root_directory, 1)

"""
运行结果:

---C:
------User
---------c.txt
---------d.txt
------a.txt
------b.txt

"""
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值