zoukankan      html  css  js  c++  java
  • sjms-3 结构型模式

    结构型模式

    适配器模式

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

    角色:
    目标接口(Target)
    待适配的类(Adaptee)
    适配器(Adapter)
    适用场景:
    想使用一个已经存在的类,而它的接口不符合你的要求(对象适配器)想使用一些已经存在的子类,但不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。

    from abc import ABCMeta, abstractmethod
    
    class Payment(metaclass=ABCMeta):
        # abstract class
        @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 ApplePay:
        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)
    
    
    # 组合
    
    # class A:
    #     pass
    #
    # class B:
    #     def __init__(self):
    #         self.a = A()
    

      

    桥模式


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

    角色:
    抽象(Abstraction)
    细化抽象(RefinedAbstraction)
    实现者(Implementor)
    具体实现者(ConcreteImplementor)

    应用场景:
    当事物有两个维度上的表现,两个维度都可能扩展时。
    优点:
    抽象和实现相分离
    优秀的扩展能力

    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):
            # 长方形逻辑
            self.color.paint(self)
    
    
    class Circle(Shape):
        name = "圆形"
        def draw(self):
            # 圆形逻辑
            self.color.paint(self)   # 调用color 对象的paint并把self形状对象传过去,方便color的paint打印
    
    
    class Line(Shape):
        name = "直线"
        def draw(self):
            # 直线逻辑
            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)
    
    
    class Blue(Color):
        def paint(self, shape):
            print("蓝色的%s" % shape.name)
    
    
    shape = Line(Blue())
    shape.draw()
    
    shape2 = Circle(Green()) # 先把color对象传过来,以便draw调用
                             # (其实draw调用的时候,是调用color的paint方法,并把shape对象传给paint让它去调用shape的name)
    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("------复合图形------")
            for g in self.children:
                g.draw()
            print("------复合图形------")
    
    
    p1 = Point(2,3)
    l1 = Line(Point(3,4), Point(6,7))    # 将简单的类对象,作为参数传递进行组合
    l2 = Line(Point(1,5), Point(2,8))
    pic1 = Picture([p1, l1, l2])
    
    
    p2 = Point(4,4)
    l3 = Line(Point(1,1), Point(0,0))
    pic2 = Picture([p2, l3])
    
    pic = Picture([pic1, pic2])
    pic.draw()
    
    """
    ------复合图形------
    ------复合图形------
    点(2, 3)
    线段[点(3, 4), 点(6, 7)]
    线段[点(1, 5), 点(2, 8)]
    ------复合图形------
    ------复合图形------
    点(4, 4)
    线段[点(1, 1), 点(0, 0)]
    ------复合图形------
    ------复合图形------
    """
    

      

    适用场景:
    表示对象的“部分-整体”层次结构(特别是结构是递归的)
    希望用户忽略组合对象与单个对象的不同,用户统一地使用组合结构中的所有对象
    优点:
    定义了包含基本对象和组合对象的类层次结构
    简化客户端代码,即客户端可以一致地使用组合对象和单个对象
    更容易增加新类型的组件

    外观模式


    内容:为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
    角色:
    外观(facade)
    子系统类(subsystem 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.cpu.stop()
            self.disk.stop()
            self.memory.stop()
    
    computer = Computer()          # 高级别的封装调用,使外观调用一致
    computer.run()
    computer.stop()
    

      

    优点:
    减少系统相互依赖
    提高了灵活性
    提高了安全性

    代理模式

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

    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
            with open(filename, 'r', encoding='utf-8') as f:
                print("读取文件内容")
                self.content = f.read()
    
        def get_content(self):
            return self.content
    
        def set_content(self, content):
            with open(self.filename, 'w', encoding='utf-8') as f:
                f.write(content)
    
    
    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)  # 在调用get_content 时才真正去打开文件
            return self.subj.get_content()
    
    
        def set_content(self, content):
            if not 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.get_content()
    
    subj = ProtectedProxy("test.txt")
    print(subj.get_content())
    # subj.set_content("abc")
    

      

    角色:
    抽象实体(Subject)
    实体(RealSubject)
    代理(Proxy)
    优点:
    远程代理:可以隐藏对象位于远程地址空间的事实
    虚代理:可以进行优化,例如根据要求创建对象
    保护代理:允许在访问一个对象时有一些附加的内务处理

  • 相关阅读:
    轻量级分布式任务调度框架(二、LTS编译、打包、部署)
    轻量级分布式任务调度框架(一、LTS简介、特点、工作流程)
    MySQL数据库学习一
    Navicat 连接 SQL Server 数据库,报错 08001
    noVNC 遇到一个错误: Uncaught TypeError: Cannot read property 'forEach' of undefined
    加强自己VPS服务器安全的一次经历
    Python 编码错误的本质和解决方案
    You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'data' at line 1
    requests爬虫请求报错:UnicodeEncodeError: 'latin-1' codec can't encode character 'u2026' in position 30
    docker无法删除镜像,Error: No such container,附docker常用命令
  • 原文地址:https://www.cnblogs.com/wenyule/p/10534249.html
Copyright © 2011-2022 走看看