zoukankan      html  css  js  c++  java
  • 设计模式二:结构型模式

    一、适配器模式

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

    角色:

    目标接口(Target)

    待适配的类(Adaptee)

    适配器(Adapter)

    两种实现方式

    类适配器:使用多继承

    对象适配器:使用组合

    适用场景:

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

    # coding : utf-8
    # create by ctz on 2017/5/25
    
    from abc import abstractmethod, ABCMeta
    
    class Payment(metaclass=ABCMeta):
        @abstractmethod
        def pay(self, money):
            raise NotImplementedError
    
    
    class Alipay(Payment):
        def pay(self, money):
            print("支付宝支付%s元"%money)
    
    
    class ApplePay(Payment):
        def pay(self, money):
            print("苹果支付%s元"%money)
    
    #------待适配类------
    
    class WechatPay:
        def huaqian(self, a, b):
            print("微信支付%s元"%(a+b))
    
    #------类适配器------
    
    class RealWeChatPay(Payment, WechatPay):
        def pay(self, money):
            return self.huaqian(money, 0)
    
    
    #------对象适配器------
    class PayAdapter(Payment):
        def __init__(self, payment):
            self.payment = payment
    
        def pay(self, money):
            return self.payment.huaqian(money, 0)
    
    
    #RealWeChatPay().pay(100)
    PayAdapter(WechatPay()).pay(1000)
    View Code

    二、组合模式

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

    角色:

    抽象组件(Component)

    叶子组件(Leaf)

    复合组件(Composite)

    客户端(Client)

     

    适用场景:

    表示对象的“部分-整体”层次结构(特别是结构是递归的) 希望用户忽略组合对象与单个对象的不同,用户统一地使用组合结构中的所有对象

    优点:

    定义了包含基本对象和组合对象的类层次结构 简化客户端代码,即客户端可以一致地使用组合对象和单个对象 更容易增加新类型的组件

    缺点:

    很难限制组合中的组件

    # coding : utf-8
    # create by ctz on 2017/5/25
    
    from abc import abstractmethod, ABCMeta
    
    class Graphic(metaclass=ABCMeta):
        @abstractmethod
        def draw(self):
            pass
    
        @abstractmethod
        def add(self, graphic):
            pass
    
        @abstractmethod
        def getchildren(self):
            pass
    
    
    class Point(Graphic):
        def __init__(self, x, y):
            self.x = x
            self.y = y
    
        def draw(self):
            print(self)
    
        def add(self, graphic):
            raise TypeError
    
        def getchildren(self):
            raise TypeError
    
        def __str__(self):
            return "点(%s, %s)" % (self.x, self.y)
    
    
    class Line(Graphic):
        def __init__(self, p1, p2):
            self.p1 = p1
            self.p2 = p2
    
        def draw(self):
            print(self)
    
        def add(self, graphic):
            raise TypeError
    
        def getchildren(self):
            raise TypeError
    
        def __str__(self):
            return "线段[%s, %s]" % (self.p1, self.p2)
    
    
    class Picture(Graphic):
        def __init__(self):
            self.children = []
    
        def add(self, graphic):
            self.children.append(graphic)
    
        def getchildren(self):
            return self.children
    
        def draw(self):
            print("------复合图形------")
            for g in self.children:
                g.draw()
            print("------END------")
    
    
    pic1 = Picture()
    pic1.add(Point(2,3))
    pic1.add(Line(Point(1,2), Point(4,5)))
    pic1.add(Line(Point(0,1), Point(2,1)))
    
    pic2 = Picture()
    pic2.add(Point(-2,-1))
    pic2.add(Line(Point(0,0), Point(1,1)))
    
    pic = Picture()
    pic.add(pic1)
    pic.add(pic2)
    
    pic.draw()
    View Code

    三、代理模式

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

    角色:

    抽象实体(Subject)

    实体(RealSubject)

    代理(Proxy)

    适用场景:

    远程代理:为远程的对象提供代理

    虚代理:根据需要创建很大的对象

    保护代理:控制对原始对象的访问,用于对象有不同访问权限时

    优点:

    远程代理:可以隐藏对象位于远程地址空间的事实

    虚代理:可以进行优化,例如根据要求创建对象

    保护代理:允许在访问一个对象时有一些附加的内务处理

    # coding : utf-8
    # create by ctz on 2017/5/26
    
    from abc import ABCMeta, abstractmethod
    
    class Subject(metaclass=ABCMeta):
        @abstractmethod
        def get_content(self):
            pass
    
    
    class RealSubject(Subject):
        def __init__(self, filename):
            self.filename = filename
            print("读取%s文件内容"%filename)
            f = open(filename)
            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)
            f.close()
    
    
    
    class ProxyA(Subject):
        def __init__(self, filename):
            self.subj = RealSubject(filename)
    
        def get_content(self):
            return self.subj.get_content()
    
    
    class ProxyB(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()
    
    
    class ProxyC(Subject):
        def __init__(self, filename):
            self.subj = RealSubject(filename)
    
        def get_content(self):
            return self.get_content()
    
        def set_content(self):
            raise PermissionError
    
        # 写一个set_content
    
    b = ProxyB("abc.txt")
    #print(b.get_content())
    View Code

     其他不一一列举了,这几个我感觉比较重要

  • 相关阅读:
    BufferedOutPutStream 字节缓冲输出流 BufferedIntPutSream 字节缓冲输入流
    Properpies
    jdk9的新特性
    try catch finally处理流的异常
    续写和换行
    write写入
    flush close
    Postman功能详解
    HyLoad压测的使用
    找出Window/Linux下 占用端口的进程
  • 原文地址:https://www.cnblogs.com/lianxuebin/p/8663896.html
Copyright © 2011-2022 走看看