Blog by Leven

Decorator-Pattern

What is decorator pattern

在软件工程中,装饰器模式允许向一个现有的对象添加新的功能,同时又不改变其结构。这种模式属于结构型模式,它是作为一个现有类的包装。
In software engineering, decorator pattern is a design pattern that alows new behaviour or function to be added to an existing individual object , without changeing the inheritance relationship or the behaviour of other objects from the same class. Decorator pattern is structural design pattern, and it is packaged of an existing object.

The usage of decorator pattern

意图:我们在设计阶段,会从子类或者抽象类,去考虑解决问题。但是在以后的扩展中,不想改变现有的类结构和让现有的子类过于膨胀,又希望给现有的对象添加一些新的功能,就会考虑使用装饰器模式。就增加功能来说,装饰器模式相比生成子类更为灵活。
如何解决:将具体功能职责划分,同时继承装饰类。
关键代码: 1、Component 类充当抽象角色,不应该具体实现。 2、修饰类引用和继承 Component 类,具体扩展类重写父类方法。
优点:装饰类可以动态扩展,不会给现有的类增加负担.
缺点:多层装饰比较复杂和难以理解。

Intent

In the process of designing, we ofen consider solving problems by defining subclasses or abstract classes. However, in the future expansion, wo do not want change the existing class structure and make the existing subclasses overstaffed, and want to add some new functions to the existing objects,we will consider using the decorator pattern.

How to solve

Divide the specific functions and resposibilities, meanwhile, inherit the decorator class.

Key code

  1. Component class act as absctract class and should not be implemented concretely.

  2. Decorate class refer and inherit Component class, extend the class concretely and rewrite methods in super class.

Advantage

Decorator class can be extended dynamically without adding burden to the existing class.

Disadvantage

Multi-layer decorators may be complex and hard to understand.

Scene and example

When we need to extend the functions of an existing object dynamically (dynamiccally increase and decrease), we use decorator pattern. For example, We have produced a new type of car and need to sell it. At this time, we can use several decorator classes, such as introducing its speed performance, safety performance and fuel-saving features so that customers can make up their minds to buy it.

class diagram

I implement this example by python3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
"""
Decorator pattern example.
"""
from abc import ABC, abstractmethod

NOT_IMPLEMENTED = "You should implement this method."

# Role: Component
class CarSale():
@abstractmethod
def displayCarInfo(self):
raise NotImplementedError(NOT_IMPLEMENTED)


# Role: Concreted Class
class CarInfo(CarSale):

def displayCarInfo(self):
print("Price: 2000$")
print("Name: TOYOTA 2020")
print("Place of production: China")

#Role: Decorator Component
class SaleTalk(CarSale):
def __init__(self,car_sale):
self._car_sale = car_sale

#override
def displayCarInfo(self):
self._car_sale.displayCarInfo()


# Role Decorator1
class SpeedDecorator(SaleTalk):
def __init__(self,car_sale):
super().__init__(car_sale)

def __showSpeed(self):
print("Speed is fast, up to 500km/h")

def displayCarInfo(self):
super().displayCarInfo()
self.__showSpeed()

# Role Decorator2
class OilDecorator(SaleTalk):
def __init__(self,car_sale):
super().__init__(car_sale)

def __showOil(self):
print("More fuel-efficient than 90% of cars")

def displayCarInfo(self):
super().displayCarInfo()
self.__showOil()


# Role Client
car_info = CarInfo()
#car_info.displayCarInfo()
speed_decorator = SpeedDecorator(car_info)
#speed_decorator.displayCarInfo()
final_decorator = OilDecorator(speed_decorator)
final_decorator.displayCarInfo()

Reference document

wiki - Decorator_pattern