原文取自大话设计模式,这里将其改为python代码进行实现
需求:现有一个用户,实现其穿衣服、穿裤子、打领带的功能,并保证其扩展性。
# 菜鸟代码
class Person():
name = ""
def __init__(self, name):
self.name = name
def WearTShirts(self):
print("大T恤")
def WearBigTrouse(self):
print("垮裤")
def WearSneakers(self):
print("破球鞋")
def WearSuit(self):
print("西装")
def WearTie(self):
print("领带")
def WearLeatherShoes(self):
print("皮鞋")
def Show(self):
print("我的装扮是:"+self.name)
if __name__ == '__main__':
print("第一种装扮:")
person1=Person("程序猿")
person1.WearBigTrouse()
person1.WearLeatherShoes()
person1.WearSneakers()
person1.Show()
print("第二种装扮:")
person2=Person("程序猿")
person2.WearSuit()
person2.WearTie()
person2.WearTShirts()
person2.Show()
# 上述代码扩展性很差,不遵守开放封闭原则
上面的代码完全没有扩展性,仿佛就是针对某个特定用户实现一样。
如若添加其它的衣服种类,或其他的用户,则上面的代码就要over了。
需求大量改变时。。。更。。。
对上面的代码进行改进:
import abc
class Person():
name=""
def __init__(self,name):
self.name=name
def show(self):
print("装扮的:"+self.name)
class Finery():
@abc.abstractmethod
def show(self):
pass
class Thirts(Finery):
def show(self):
print("大T恤")
class WearBigTrouse(Finery):
def show(self):
print("垮裤")
class WearSneakers(Finery):
def show(self):
print("破球鞋")
class WearSuit(Finery):
def show(self):
print("西装")
class WearTie(Finery):
def show(self):
print("领带")
class WearLeatherShoes(Finery):
def show(self):
print("皮鞋")
if __name__ == '__main__':
print("第一种装扮:")
person=Person("程序猿")
dtx=Thirts()
kk=WearBigTrouse()
pqx=WearSneakers()
dtx.show()
kk.show()
pqx.show()
person.show()
print("第二种装扮:")
person=Person("程序猿")
dtx=WearSuit()
kk=WearLeatherShoes()
pqx=WearTie()
dtx.show()
kk.show()
pqx.show()
person.show()
# 上面的代码将各种服装进行了扩展,但是调用起来还是方便
改进的代码虽然对衣服类进行了抽象封装,具有了扩展性,但是调用起来非常麻烦。
比如说:当上面的【程序猿】穿任意一个衣服时,都要将这个【裸体】【程序猿】进行传递,没有串起来。
即【程序猿】穿了【上衣】后、常规来讲肯定是将【穿过上衣的程序猿】传递给【下一个衣服】。
而不是将【裸体】的【程序猿】进行传递。
即没有按需进行顺序控制。
对上述的代码再次改版,用装饰者模式进行实现:
装饰者模式:动态的给对象添加一些额外的职责!
import abc
# 定义一个对象的接口,动态的给对象添加职责
class Component():
@abc.abstractmethod
def Operation(self):
pass
# 具体的装饰对象,给具体的对象添加职责或功能
class ConcreteComPonent(Component):
def __init__(self):
print("我是小明,我是一个对象!!")
def Operation(self):
print("我要开始穿衣服了.....")
# 装饰抽象类,从外类来扩展对象的接口的方法,这个类就是用扩展对象接口的
# 这个类主要用来服务具体的装饰对象的,即保留服务对象
# 其中component指的就是服务对象-小明
class Decorator(Component):
component=None
def __init__(self):
print("创建了装饰对象")
def setComponent(self,component):
self.component=component
def Operation(self):
if self.component!=None:
self.component.Operation()
# 装饰对象A
class ConcreteDecoratorA(Decorator):
addedState="A"
def __init__(self):
print("创建了装饰A对象")
def Operation(self):
super().Operation()
self.addedState="修改装饰对象A的属性为:AAAAA"
print("穿上衣")
# 装饰对象B
class ConcreteDecoratorB(Decorator):
addedState="B"
def __init__(self):
print("创建了装饰B对象")
def Operation(self):
super().Operation()
self.addedState="修改装饰对象B的属性为:BBBBB"
print("穿裤子")
# 装饰对象B独有的操作
def AddedBehavior(self):
print("开始吃饭")
if __name__ == '__main__':
# 具体的装饰对象
c=ConcreteComPonent()
# 创建装饰对象A
a1=ConcreteDecoratorA()
# 创建装饰对象B
b1=ConcreteDecoratorB()
# 将具体对象小明传给装饰对象A,这句话执行后装饰对象A中包含了小明,即A(小明)
a1.setComponent(c)
# 装饰对象A 传给装饰对象B,这句话执行后,装饰对象B中包含了A,即B(A(小明))
b1.setComponent(a1)
# 开始执行穿衣操作
b1.Operation()
b1.AddedBehavior()
这个模式的精髓在于将【对象】装进A、将【A】装进【B】,最后调用【B】的独有方法(等同于一条线将所有事情串起来)
注:也可以在A中创建A独有的方法并且调用,然后再传给B
其中:
调用【B】的方法时、会获取到【A】(因为B对象的component这时候存储的时A)
注:对象【A】是通过Super()方法获取到的,没有这个方法则获取不到
获取到【A】后,调用了其Operation()方法,然后通过这个方法得到了【小明】,与上述同理,也是通过Super()方法获取到的小明,然后A再调用自己的方法!!!
运行结果如下:
调用的时候有点像递归,即一层一层网上走,走到最顶层是,开始一层一层往下执行。
稍微有点难理解,但明白了还是很有帮助的。
一定要注意Super()方法,整个代码都围绕着这个方法在转!!!
一定要注意Super()方法,整个代码都围绕着这个方法在转!!!
一定要注意Super()方法,整个代码都围绕着这个方法在转!!!
如有错误,敬请指正!!!