一分钟了解decorator pattern
Decorator Pattern 是 Python 中常见的一种设计模式,它允许你在不改变原有对象的情况下,动态地为对象添加功能。这个模式通常用于需要多个扩展功能的场景,它可以优雅地实现这些功能的添加和组合,而不需要写大量的重复代码。
下面我们会用实例来详细说明这个模式。
在这个例子中,我们假设有一家咖啡店,卖各种咖啡,并且可以添加各种配料,比如牛奶、糖和巧克力酱等。我们需要设计一个程序来计算一杯咖啡的价格及其配料。
首先,我们定义一个抽象基类 Beverage,它有两个方法 get_description() 和 cost()。这个类会被所有饮料类继承。
from abc import ABC, abstractmethod
class Beverage(ABC):
@abstractmethod
def get_description(self):
pass
@abstractmethod
def cost(self):
pass
然后我们定义三个具体饮料类,分别是 Espresso、Latte 和 Cappuccino。它们都继承自 Beverage,并实现了它们各自的价格和描述。
class Espresso(Beverage):
def get_description(self):
return 'Espresso'
def cost(self):
return 2.0
class Latte(Beverage):
def get_description(self):
return 'Latte'
def cost(self):
return 3.0
class Cappuccino(Beverage):
def get_description(self):
return 'Cappuccino'
def cost(self):
return 3.5
接下来,我们定义一个装饰器类 CondimentDecorator,它也是一个饮料,但它有自己的价格和描述,用来增加饮料的配料。它继承自 Beverage,并重写了它的 get_description() 和 cost() 方法。
class CondimentDecorator(Beverage):
def __init__(self, beverage):
self.beverage = beverage
@abstractmethod
def get_description(self):
pass
def cost(self):
return self.beverage.cost()
然后我们定义三个具体装饰器类,分别是 Milk、Sugar 和 ChocolateSauce。它们都继承自 CondimentDecorator,并实现了它们各自的价格和描述。它们的构造函数需要一个被装饰的饮料对象。
class Milk(CondimentDecorator):
def __init__(self, beverage):
super().__init__(beverage)
self.price = 0.5
self.description = ' with milk'
def get_description(self):
return self.beverage.get_description() + self.description
def cost(self):
return self.beverage.cost() + self.price
class Sugar(CondimentDecorator):
def __init__(self, beverage):
super().__init__(beverage)
self.price = 0.3
self.description = ' with sugar'
def get_description(self):
return self.beverage.get_description() + self.description
def cost(self):
return self.beverage.cost() + self.price
class ChocolateSauce(CondimentDecorator):
def __init__(self, beverage):
super().__init__(beverage)
self.price = 0.8
self.description = ' with chocolate sauce'
def get_description(self):
return self.beverage.get_description() + self.description
def cost(self):
return self.beverage.cost() + self.price
最后,我们来测试这个程序。我们创建了一个 Espresso 对象,并加入 Milk 和 ChocolateSauce 两个装饰器对象。最后,我们输出这杯咖啡的描述和价格。
espresso = Espresso()
espresso_with_milk_chocolate = Milk(ChocolateSauce(espresso))
print(f'Description: {espresso_with_milk_chocolate.get_description()}')
print(f'Price: {espresso_with_milk_chocolate.cost()}')
运行这个程序,我们可以看到最终的输出为 “Description: Espresso with chocolate sauce with milk” 和 “Price: 3.3”,也就是 Espresso 加上 ChocolateSauce 和 Milk 的价格之和。
这个例子中,我们使用 Decorator Pattern 来实现咖啡的配料功能,在不修改原有饮料类的情况下,动态地添加和组合配料,使得代码更加优雅和易于扩展。如果我们要添加更多的配料,我们只需要创建新的装饰器类,并将它加入到饮料对象中即可。