意图:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。
主要解决:一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。
何时使用:在不想增加很多子类的情况下扩展类。
如何解决:将具体功能职责划分,同时继承装饰者模式。
python实现
"""
装饰器可以是一个函数,也可以是一个类(必须要实现__call__方法,使其是callable的)。
同时装饰器不仅可以修改一个函数,还可以修饰一个类
"""
class ClassDecorator:
def __init__(self,func):
self.__num_of_call =0
self.__func = func
def __call__(self, *args, **kwargs):
self.__num_of_call +=1
obj = self.__func(*args,**kwargs)
print("创建%s的第%d个实例 %s" % (self.__func.__name__,self.__num_of_call,id(obj)))
return obj
@ClassDecorator
class MyClass:
def __init__(self,name):
self.__name = name
def get_name(self):
return self.__name
if __name__ =="__main__":
tony = MyClass("tony")
karry = MyClass("karry")
print(tony.get_name())
print(karry.get_name())
print(id(tony))
print(id(karry))
from abc import ABCMeta, abstractmethod
"""
装饰模式优点:
在不改变代码的情况下可以添加额外的功能
"""
class Person(metaclass=ABCMeta):
""" 人 """
def __init__(self, name):
self._name = name
@abstractmethod
def wear(self):
print("穿着:")
class Engineer(Person):
""" 工程师 """
def __init__(self, name, skill):
super().__init__(name)
self._skill = skill
def get_skill(self):
return self._skill
def wear(self):
print("我是:" + self.get_skill() + "工程师" + self._name, end=' ')
super().wear()
class Teacher(Person):
def __init__(self, name, title):
super().__init__(name)
self._title = title
def get_title(self):
return self._title
def wear(self):
print("我是:" + self._name + self.get_title(), end=' ')
super().wear()
class ClothesDecorator(Person):
""" 服装装饰器的基类 """
def __init__(self, person):
super().__init__(person)
self._decorated = person
def wear(self):
self._decorated.wear()
self.decorate()
@abstractmethod
def decorate(self):
pass
class CasualPantDecorator(ClothesDecorator):
""" 休闲裤装饰器 """
def __init__(self, person):
super().__init__(person)
def decorate(self):
print("一条卡其色休闲裤")
class BeltDecorator(ClothesDecorator):
""" 腰带装饰器 """
def __init__(self, person):
super().__init__(person)
def decorate(self):
print("一条银色针扣头的黑色腰带")
class LeatherShoesDecorator(ClothesDecorator):
""" 皮鞋装饰器 """
def __init__(self, person):
super().__init__(person)
def decorate(self):
print("一双深色休闲皮鞋")
class KnittedSweaterDecorator(ClothesDecorator):
""" 针织毛衣装饰器 """
def __init__(self, person):
super().__init__(person)
def decorate(self):
print("一件紫红色针织毛衣")
class WhiteShirtDecorator(ClothesDecorator):
""" 白色衬衫装饰器 """
def __init__(self, person):
super().__init__(person)
def decorate(self):
print("一件紫红色针织毛衣")
class GlassesDecorator(ClothesDecorator):
""" 眼睛装饰器 """
def __init__(self, person):
super().__init__(person)
def decorate(self):
print("一副方形黑框眼睛")
if __name__ == '__main__':
tony = Engineer("Tony", "python")
pant = CasualPantDecorator(tony)
belt = BeltDecorator(pant)
shoes = LeatherShoesDecorator(belt)
shirt = WhiteShirtDecorator(shoes)
sweater = KnittedSweaterDecorator(shirt)
glasses = GlassesDecorator(sweater)
glasses.wear()
print()
# 下面写法将多个对象的创建过程合在了一起,是一种优雅的写法
decorateTeacher = GlassesDecorator(WhiteShirtDecorator(LeatherShoesDecorator(Teacher("wells", "教授"))))
decorateTeacher.wear()
我是:python工程师Tony 穿着:
一条卡其色休闲裤
一条银色针扣头的黑色腰带
一双深色休闲皮鞋
一件紫红色针织毛衣
一件紫红色针织毛衣
一副方形黑框眼睛
我是:wells教授 穿着:
一双深色休闲皮鞋
一件紫红色针织毛衣
一副方形黑框眼睛
dart 实现
abstract class Shape {
void draw();
}
class Rectangle implements Shape {
@override
void draw() {
// TODO: implement draw
print("Shape Rect");
}
}
class Circle implements Shape {
@override
void draw() {
// TODO: implement draw
print("Shape Circle");
}
}
abstract class ShapeDecorator implements Shape {
Shape _decoratedShape;
ShapeDecorator(this._decoratedShape);
void draw() {
_decoratedShape.draw();
}
}
class RedShapeDecorator extends ShapeDecorator {
RedShapeDecorator(Shape decoratedShape) : super(decoratedShape);
@override
void draw() {
_decoratedShape.draw();
setRedBorder(_decoratedShape);
}
void setRedBorder(Shape decoratedShape) {
print("border color red");
}
}
void main(List<String> args) {
Shape circle = Circle();
Shape redCircle = RedShapeDecorator(Circle());
Shape redRectangle = RedShapeDecorator(Rectangle());
print("circle with normal border");
circle.draw();
print("Circle of red border");
redCircle.draw();
print("rectangle of red border");
redRectangle.draw();
}
// [Running] dart "e:\source\dart\designpatterns\Decorator.dart"
// circle with normal border
// Shape Circle
// Circle of red border
// Shape Circle
// border color red
// rectangle of red border
// Shape Rect
// border color red