every blog every motto: You can do more than you think.
https://blog.csdn.net/weixin_39190382?type=blog
0. 前言
【设计模式|上】【创建型】
【设计模式 | 中】【结构型】
- 适配器模式
- 代理模式
- 装饰器模式
- 桥接模式
- 组合模式
- 外观模式
- 享元模式
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