【设计模式·Python】结构型模式

设计模式中,结构型模式有以下几种:

  • 适配器模式
  • 桥模式
  • 组合模式
  • 装饰模式
  • 外观模式
  • 享元模式
  • 代理模式

适配器模式

  • 将一个类的接口转换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
  • 两种实现方式:
    类适配器:使用多继承
    对象适配器:使用组合
# 适配器模式
from abc import ABCMeta, abstractmethod


class Payment(metaclass=ABCMeta):
    @abstractmethod
    def pay(self, money):
        pass


class Alipay(Payment):
    def pay(self, money):
        print("支付宝支付%d元。" % money)


class WechatPay(Payment):
    def pay(self, money):
        print("微信支付%d元。" % money)


class BankPay:
    def cost(self, money):
        print("银联支付%d元。" % money)

# 类适配器
# class NewBankPay(Payment, BankPay):
#     def pay(self, money):
#         self.cost(money)


# 对象适配器
class PaymentAdapter(Payment):
    def __init__(self, payment):
        self.payment = payment

    def pay(self, money):
        self.payment.cost(money)


p = PaymentAdapter(BankPay())
p.pay(100)

桥模式

  • 将一个事物的两个维度分离,使其都可以独立地变化。

# 桥模式
# 将一个事物的两个维度分离,使其都可以独立地变化。

from abc import ABCMeta, abstractmethod


class Shape(metaclass=ABCMeta):
    def __init__(self, color):
        self.color = color

    @abstractmethod
    def draw(self):
        pass


class Color(metaclass=ABCMeta):
    @abstractmethod
    def paint(self, shape):
        pass


class Rectangle(Shape):
    name = "长方形"

    def draw(self):
        # TODO:矩形逻辑
        self.color.paint(self)


class Circle(Shape):
    name = "圆形"

    def draw(self):
        # TODO:原型逻辑
        self.color.paint(self)


class Red(Color):
    def paint(self, shape):
        print("红色的%s" % shape.name)


class Green(Color):
    def paint(self, shape):
        print("绿色的%s" % shape.name)


shape = Rectangle(Red())
shape.draw()

shape2 = Circle(Green())
shape2.draw()

组合模式

  • 将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式是用户对单个对象和组合对象的使用都具有一致性。
  • 角色:
    抽象组件(Component)
    叶子组件(Leaf)
    复合组件(Composite)
    客户端(Client)

# 组合模式

from abc import ABCMeta, abstractmethod
# 抽象组件


class Graphic(metaclass=ABCMeta):
    @abstractmethod
    def draw(self):
        pass


# 叶子组件
class Point(Graphic):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __str__(self):
        return "点(%s, %s)" % (self.x, self.y)

    def draw(self):
        print(str(self))


class Line(Graphic):
    def __init__(self, p1, p2):
        self.p1 = p1
        self.p2 = p2

    def __str__(self):
        return "线段(%s, %s)" % (self.p1, self.p2)

    def draw(self):
        print(str(self))


# 复合组件
class Picture(Graphic):
    def __init__(self, iterable):
        self.children = []
        for g in iterable:
            self.add(g)

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

    def draw(self):
        print("*"* 100)
        print("----复合图形 start----")
        for g in self.children:
            g.draw()
        print("----复合图形 end----")


# 线段
l = Line(Point(1, 1), Point(2, 2))
print(l)

# 点跟线组合
p1 = Point(2, 3)
l1 = Line(Point(2, 4), Point(6, 7))
l2 = Line(Point(1, 5), Point(2, 8))
pic1 = Picture([p1, l1, l2])
# pic1.draw()

# pic1跟 pic2再次组合
l3 = Line(Point(2, 4), Point(6, 7))
l4 = Line(Point(1, 5), Point(2, 8))
pic2 = Picture([l3, l4])
pic3 = Picture([pic1, pic2])
pic3.draw()


外观模式

  • 为子系统的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
  • 角色:
    外观(Facade)
    子系统类(Sub system classes)

# 外观模式
#

class CPU:
    def run(self):
        print("CPU开始运行")

    def stop(self):
        print("CPU停止运行")


class Disk:
    def run(self):
        print("硬盘开始运行")

    def stop(self):
        print("硬盘停止运行")


class Memory:
    def run(self):
        print("内存开始运行")

    def stop(self):
        print("内存停止运行")


class Computer:     # Facade
    def __init__(self):
        self.cpu = CPU()
        self.disk = Disk()
        self.memory = Memory()

    def run(self):
        self.cpu.run()
        self.disk.run()
        self.memory.run()
    
    def stop(self):
        self.memory.stop()
        self.disk.stop()
        self.cpu.stop()


computer = Computer()
computer.run()
print(f"计算机正在运行。。。")
computer.stop()

代理模式

  • 为其他对象提供一种代理以控制对这个对象的访问
  • 应用场景:
    远程代理:为远程的对象提供代理
    虚代理:根据需要创建很大的对象
    保护代理:控制对原始对象的访问,用于对象有不同访问权限时。

# 代理模式
"""
角色:
    抽象实体(Subject)
    实体(RealSubject)
    代理(Proxy)
"""

from abc import ABCMeta, abstractmethod


class Subject(metaclass=ABCMeta):
    @abstractmethod
    def get_content(self):
        pass

    @abstractmethod
    def set_content(self, content):
        pass


class RealSubject(Subject):
    def __init__(self, filename):
        self.filename = filename
        f = open(filename, 'r')
        self.content = f.read()
        f.close()

    def get_content(self):
        return self.content

    def set_content(self, content):
        f = open(self.filename, 'w')
        f.write(content)
        self.content = content
        f.close()


class VirtualProxy(Subject):
    def __init__(self, filename):
        self.filename = filename
        self.subj = None

    def get_content(self):
        if not self.subj:
            self.subj = RealSubject(self.filename)
        return self.subj.get_content()

    def set_content(self, content):
        if not self.subj:
            self.subj = RealSubject(self.filename)
        return self.subj.set_content(content)


class ProtectedProxy(Subject):
    def __init__(self, filename):
        self.subj = RealSubject(filename)

    def get_content(self):
        return self.subj.get_content()

    def set_content(self, content):
        raise PermissionError("无写入权限")


subj = RealSubject("test.txt")
# subj.set_content("test, cai")
# print(subj.get_content())
print("---- VirtualProxy")
v_subj = VirtualProxy("test.txt")
print(v_subj.get_content())

print("---- ProtectedProxy")
p_subj = ProtectedProxy("test.txt")
print(p_subj.get_content())
p_subj.set_content("aaa")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值