• 设计模式二:结构型模式



    结构型模式(7)种:适配器模式,桥模式,组合模式,装饰模式,外观模式,享元模式,代理模式

    1、适配器模式

    内容:将一个类的接口转换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

    两种实现方式:

    • 类适配器:使用多继承
    • 对象适配器:使用组合 

    角色:

      1、目标接口(target)

      2、待适配的类(Adaptee)

      3、适配器(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 PaymentAdapter(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)
    
    ##
     目标接口:Payment
     待适配的类:BankPay, ApplePay
     适配器:PaymentAdapter
    View Code

    2、桥模式

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

    角色:

    • 抽象(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)
    
    
    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())
    shape2.draw()
    
    
    ##
        抽象:Shape
        细化抽象:Color
        实现者:Red,Green,Blue
        具体实现者:Rectangle,Circle, Line
    View Code

    3、组合模式

    内容:将对象组合成树型结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

    角色:

    • 抽象组件(Component)
    • 叶子组件(Leaf)
    • 复合组件(Composite)
    • 客户端(Client)

    适用场景:

      表示对象的"部分-整体"层次结构(特别是结构是递归的)

      希望用户忽略组合对象与单个对象的不同,用户统一地适用组合结构中的所有对象。

    优点:

    1. 定义了包含基本对象和组合对象的层次结构
    2. 简化客户端代码,即客户端可以一直地使用组合对象和单个对象
    3. 更容易增加新类型的组件
    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()
    View Code

    4、外观模式

    内容:为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

    角色:

    • 外观(facade)
    • 子系统类(subsystem classes)

    优点:

    1. 减少系统相互依赖
    2. 提高了灵活性
    3. 提高了安全性
    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:
        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()
    View Code

    5、代理模式

    内容:为其他对象提供一种代理以控制对这个对象的访问。

    应用场景:

    • 远程代理:为远程的对象提供代理
    • 虚代理:根据需要创建很大的对象
    • 保护代理:控制对原始对象的访问,用于对象有不同访问权限时

    角色:

      抽象实体(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', encoding="utf-8")
            print("读取文件内容")
            self.content = f.read()
            f.close()
    
        def get_content(self):
            return self.content
    
        def set_content(self, content):
            f = open(self.filename, 'w', encoding="utf-8")
            f.write(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 = ProtectedProxy("test.txt")
    print(subj.get_content())
    subj.set_content("abc")
    View Code
  • 相关阅读:
    Kafka:ZK+Kafka+Spark Streaming集群环境搭建(二十六)Structured Streaming:WARN clients.NetworkClient: Error while fetching metadata with correlation id 1 : {my-topic=LEADER_NOT_AVAILABLE}
    Kafka:ZK+Kafka+Spark Streaming集群环境搭建(二十五)Structured Streaming:同一个topic中包含一组数据的多个部分,按照key它们拼接为一条记录(以及遇到的问题)。
    Kafka:ZK+Kafka+Spark Streaming集群环境搭建(二十四)Structured Streaming:Encoder
    Kafka:ZK+Kafka+Spark Streaming集群环境搭建(二十三)Structured Streaming遇到问题:Set(TopicName-0) are gone. Some data may have been missed
    Structured Streaming编程向导
    Kafka:ZK+Kafka+Spark Streaming集群环境搭建(二十二)Spark Streaming接收流数据及使用窗口函数
    Linux:磁盘挂载
    Kafka:ZK+Kafka+Spark Streaming集群环境搭建(二十一)NIFI1.7.1安装
    Spark参数设置的方式
    mydumper安装、原理介绍
  • 原文地址:https://www.cnblogs.com/Xuuuuuu/p/10861657.html
Copyright © 2020-2023  润新知