设计模式十九装饰模式:边学边做个生成电子书的工具(python+dart)

193 阅读3分钟

意图:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。

主要解决:一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。

何时使用:在不想增加很多子类的情况下扩展类。

如何解决:将具体功能职责划分,同时继承装饰者模式。

image.png

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