【设计模式|中】结构型模式

every blog every motto: You can do more than you think.
https://blog.csdn.net/weixin_39190382?type=blog

0. 前言

【设计模式|上】【创建型】
【设计模式 | 中】【结构型】

  1. 适配器模式
  2. 代理模式
  3. 装饰器模式
  4. 桥接模式
  5. 组合模式
  6. 外观模式
  7. 享元模式

【设计模式 | 下】【行为型】

1. 正文

1.2 结构型

1.2.1 适配器模式(Adapter)

场景: 不改变接口的情况下,修改实现功能是实现方式

'''
Adapter
'''
#适配器模式
# 将一个类的接口转换成客户希望的另外一个接口。使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
# 应用场景:希望复用一些现存的类,但是接口又与复用环境要求不一致。
 
def printInfo(info):
    print(info)
 
#球员类
class Player():
    name = ''
    def __init__(self,name):
        self.name = name
 
    def Attack(self,name):
        pass
 
    def Defense(self):
        pass
 
#前锋
class Forwards(Player):
    def __init__(self,name):
        Player.__init__(self,name)
 
    def Attack(self):
        printInfo("前锋%s 进攻" % self.name)
 
    def Defense(self):
        printInfo("前锋%s 防守" % self.name)
 
#中锋(目标类)
class Center(Player):
   def __init__(self,name):
       Player.__init__(self,name)
 
   def Attack(self):
       printInfo("中锋%s 进攻" % self.name)
 
   def Defense(self):
       printInfo("中锋%s 防守" % self.name)
 
#后卫
class Guards(Player):
   def __init__(self,name):
       Player.__init__(self,name)
 
   def Attack(self):
       printInfo("后卫%s 进攻" % self.name)
 
   def Defense(self):
       printInfo("后卫%s 防守" % self.name)
 
#外籍中锋(待适配类)
#中锋
class ForeignCenter(Player):
    name = ''
    def __init__(self,name):
        Player.__init__(self,name)
 
    def ForeignAttack(self):
        printInfo("外籍中锋%s 进攻" % self.name)
 
    def ForeignDefense(self):
        printInfo("外籍中锋%s 防守" % self.name)
 
 
#翻译(适配类)
class Translator(Player):
    foreignCenter = None
    def __init__(self,name):
        self.foreignCenter = ForeignCenter(name)
 
    def Attack(self):
        self.foreignCenter.ForeignAttack()
 
    def Defense(self):
        self.foreignCenter.ForeignDefense()
 
 
def clientUI():
    b = Forwards('巴蒂尔')
    ym = Guards('姚明')
    m = Translator('麦克格雷迪')
 
    b.Attack()
    m.Defense()
    ym.Attack()
    b.Defense()
    return
 
if __name__ == '__main__':
    clientUI()

1.2.2 代理模式

场景: 不方便直接访问,需要中间过程作为过渡才能访问

 
'''
Proxy
'''
 
# 代理模式
# 应用特性:需要在通信双方中间需要一些特殊的中间操作时引用,多加一个中间控制层。
# 结构特性:建立一个中间类,创建一个对象,接收一个对象,然后把两者联通起来
 
class sender_base:
    def __init__(self):
        pass
 
    def send_something(self, something):
        pass
 
 
class send_class(sender_base):
    def __init__(self, receiver):
        self.receiver = receiver
 
    def send_something(self, something):
        print("SEND " + something + ' TO ' + self.receiver.name)
 
 
class agent_class(sender_base):
    def __init__(self, receiver):
        self.send_obj = send_class(receiver)
 
    def send_something(self, something):
        self.send_obj.send_something(something)
 
 
class receive_class:
    def __init__(self, someone):
        self.name = someone
 
 
if '__main__' == __name__:
    receiver = receive_class('Burgess')
    agent = agent_class(receiver)
    agent.send_something('agentinfo')
 
    print(receiver.__class__)
    print(agent.__class__)

1.2.3 装饰模式

 
'''
Decorator
'''
 
class foo(object):
    def f1(self):
        print("original f1")
 
    def f2(self):
        print("original f2")
 
 
class foo_decorator(object):
    def __init__(self, decoratee):
        self._decoratee = decoratee
 
    def f1(self):
        print("decorated f1")
        self._decoratee.f1()
 
    def __getattr__(self, name):
        return getattr(self._decoratee, name)
 
u = foo()
v = foo_decorator(u)
v.f1()
v.f2()

1.2.4 桥模式(Bridge)

'''
Bridge
'''
class AbstractRoad(object):
    '''路基类'''
    car = None
 
class AbstractCar(object):
    '''车辆基类'''
 
    def run(self):
        raise NotImplementedError
 
class Street(AbstractRoad):
    '''市区街道'''
 
    def run(self):
        self.car.run()
        print("在市区街道上行驶")
 
class SpeedWay(AbstractRoad):
    '''高速公路'''
 
    def run(self):
        self.car.run()
        print("在高速公路上行驶")
 
 
class Car(AbstractCar):
    '''小汽车'''
    def run(self):
        print("小汽车在")
 
class Bus(AbstractCar):
    '''公共汽车'''
    def run(self):
        print("公共汽车在")
 
 
if __name__ == "__main__":
    #小汽车在高速上行驶
    road1 = SpeedWay()
    road1.car = Car()
    road1.run()
 
    #
    road2 = SpeedWay()
    road2.car = Bus()
    road2.run()
 
    road3 = Street()
    road3.car = Bus()
    road3.run()

1.2.5 组合模式(Composite)

"""
Composite
"""
 
 
class Component:
    def __init__(self, strName):
        self.m_strName = strName
 
    def Add(self, com):
        pass
 
    def Display(self, nDepth):
        pass
 
 
class Leaf(Component):
    def Add(self, com):
        print("leaf can't add")
 
 
    def Display(self, nDepth):
        strtemp = "-" * nDepth
        strtemp = strtemp + self.m_strName
        print(strtemp)
 
class Composite(Component):
    def __init__(self, strName):
        self.m_strName = strName
        self.c = []
 
    def Add(self, com):
        self.c.append(com)
 
    def Display(self, nDepth):
        strtemp = "-" * nDepth
        strtemp = strtemp + self.m_strName
        print(strtemp)
        for com in self.c:
            com.Display(nDepth + 2)
 
 
if __name__ == "__main__":
    p = Composite("Wong")
    p.Add(Leaf("Lee"))
    p.Add(Leaf("Zhao"))
    p1 = Composite("Wu")
    p1.Add(Leaf("San"))
    p.Add(p1)
    p.Display(1)

1.2.6 外观模式(Facade)

'''
Facade
 
外观模式(Facade),为子系统中的一组接口提供一个一致的界面,定义一个高层接口,这个接口使得这一子系统更加容易使用。
在以下情况下可以考虑使用外观模式:
(1)设计初期阶段,应该有意识的将不同层分离,层与层之间建立外观模式。
(2) 开发阶段,子系统越来越复杂,增加外观模式提供一个简单的调用接口。
(3) 维护一个大型遗留系统的时候,可能这个系统已经非常难以维护和扩展,但又包含非常重要的功能,为其开发一个外观类,以便新系统与其交互。
 
优点编辑
(1)实现了子系统与客户端之间的松耦合关系。
(2)客户端屏蔽了子系统组件,减少了客户端所需处理的对象数目,并使得子系统使用起来更加容易。
'''
 
 
def printInfo(info):
    print(info)
 
class Stock():
    name = '股票'
    def buy(self):
        printInfo('买 '+self.name)
 
    def sell(self):
        printInfo('卖 '+self.name)
 
class ETF():
    name = '指数型基金'
    def buy(self):
        printInfo('买 '+self.name)
 
    def sell(self):
        printInfo('卖 '+self.name)
 
class Future():
    name = '期货'
    def buy(self):
        printInfo('买 '+self.name)
 
    def sell(self):
        printInfo('卖 '+self.name)
 
class NationDebt():
    name = '国债'
    def buy(self):
        printInfo('买 '+self.name)
 
    def sell(self):
        printInfo('卖 '+self.name)
 
class Option():
    name = '权证'
    def buy(self):
        printInfo('买 '+self.name)
 
    def sell(self):
        printInfo('卖 '+self.name)
 
#基金
class Fund():
 
    def __init__(self):
        self.stock = Stock()
        self.etf = ETF()
        self.future = Future()
        self.debt = NationDebt()
        self.option = Option()
 
    def buyFund(self):
        self.stock.buy()
        self.etf.buy()
        self.debt.buy()
        self.future.buy()
        self.option.buy()
 
    def sellFund(self):
        self.stock.sell()
        self.etf.sell()
        self.future.sell()
        self.debt.sell()
        self.option.sell()
 
def clientUI():
    myFund = Fund()
    myFund.buyFund()
    myFund.sellFund()
    return
 
 
if __name__ == '__main__':
    clientUI()

1.2.7 享元模式–Flyweight

'''
Flyweight
'''
class FlyweightBase(object):
    _instances = dict()  #皴法实例化的对象内存地址
    def __init__(self,*args,**kwargs):
        #继承的子类必须初始化
        raise NotImplementedError
 
    def __new__(cls, *args, **kwargs):
        print(cls._instances,type(cls))  #cls 就是你要实例化的子类如:obj = Spam(1,abc)
        return cls._instances.setdefault(
            (cls,args,tuple(kwargs.items())), #key   (实例和参数)obj = Spam(y,x)
            super(FlyweightBase,cls).__new__(cls)  # value  #实例化新的对象的内存地址
            # 调用自身的_instances字典,如果没有往父类找_instances字典
            # setdefault:判断_instances字典是否有该key:obj = Spam(y,x)实例 ,
            #               如果有,返回该key的value(上次实例化对象(内存地址))
            # setdefault: 如果找不到key:obj = Spam(y,x)实例 ,就在_instances字典就创建该key,value为新实例化对象(内存地址)
            #               返回该新创建key的value(该次实例化的对象(内存地址)
            # 这也就说明你实例化对象的时候,如果形参相同的话,不用实例化,直接返回已存在的实例的内存)
        )
class Spam(FlyweightBase):
    '''精子类'''
 
 
    def test_data(self):
        pass
    def __init__(self,a,b):
        self.a = a
        self.b = b
 
    def test_data(self):
        print("精子准备好了",self.a,self.b)
class Egg(FlyweightBase):
    '''卵类'''
    def __init__(self,x,y):
        self.x = x
        self.y = y
 
    def test_data(self):
        print("卵子准备好了",self.x,self.y)
 
 
 
spam1 = Spam(1,'abc')
spam2 = Spam(1,'abc')
spam3 = Spam(3,'DEF')
 
egg1 = Egg(1,'abc')
print(id(spam1),id(spam2),id(spam3))
 
#egg2 = Egg(4,'abc')
# assert spam1 is spam2
# assert egg1 is not spam1
# print(id(spam1),id(spam2))
# spam2.test_data()
# egg1.test_data()
# print(egg1._instances)
# print(egg1._instances.keys())

[1] https://blog.csdn.net/hbu_pig/article/details/80509629
[2] https://zhuanlan.zhihu.com/p/92051694
[3] https://blog.csdn.net/weixin_41624982/article/details/86843476
[4] https://zhuanlan.zhihu.com/p/78985339
[5] https://www.jianshu.com/p/013985a58841
[6] https://blog.csdn.net/weixin_42234345/article/details/106992960
[7] https://blog.csdn.net/longyanbuhui/article/details/103781286
[8] https://blog.csdn.net/ericzhong83/article/details/7596420
[9] https://zhuanlan.zhihu.com/p/591820449
[10] https://blog.csdn.net/hbuxiaofei/article/details/106888178
[11] https://blog.csdn.net/hbuxiaofei/article/details/106875759
[12] https://zhuanlan.zhihu.com/p/56360529
[13] https://blog.csdn.net/qq_38923792/article/details/100920500
[14] https://blog.csdn.net/qq_29518275/article/details/119450806
[15] https://www.cnblogs.com/lifei01/p/13273970.html
[16] https://blog.csdn.net/hbu_pig/article/details/80568749

猜你喜欢

转载自blog.csdn.net/weixin_39190382/article/details/132057504