装饰器模式python实例

装饰器模式

定义

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

实例

我们通过下面的实例来演示装饰器模式的用法。其中,我们将把一个形状装饰上不同的颜色,同时又不改变形状类。
1、孙悟空有 72 变,当他变成"庙宇"后,他的根本还是一只猴子,但是他又有了庙宇的功能。 2、不论一幅画有没有画框都可以挂在墙上,但是通常都是有画框的,并且实际上是画框被挂在墙上。在挂在墙上之前,画可以被蒙上玻璃,装到框子里;这时画、玻璃和画框形成了一个物体。

介绍

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

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

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

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

关键代码: 1、Component 类充当抽象角色,不应该具体实现。 2、修饰类引用和继承 Component 类,具体扩展类重写父类方法。

优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

缺点:多层装饰比较复杂。

使用场景: 1、扩展一个类的功能。 2、动态增加功能,动态撤销。

注意事项:可代替继承。

装饰模式的结构

装饰模式包含以下4个角色: Component(抽象构件) ConcreteComponent(具体构件) Decorator(抽象装饰类) ConcreteDecorator(具体装饰类)

#又提到了那个快餐点餐系统,不过今天我们只以其中的一个类作为主角:饮料类。首先,回忆下饮料类:
class Beverage():
    name = ""
    price = 0.0
    type = "BEVERAGE"
    def getPrice(self):
        return self.price
    def setPrice(self, price):
        self.price = price
    def getName(self):
        return self.name

class coke(Beverage):
    def __init__(self):
        self.name = "coke"
        self.price = 4.0

class milk(Beverage):
    def __init__(self):
        self.name = "milk"
        self.price = 5.0

#除了基本配置,快餐店卖可乐时,可以选择加冰,如果加冰的话,要在原价上加0.3元;
# 卖牛奶时,可以选择加糖,如果加糖的话,要原价上加0.5元。怎么解决这样的问题?
# 可以选择装饰器模式来解决这一类的问题。首先,定义装饰器类:
class drinkDecorator():
    def getName(self):
        pass
    def getPrice(self):
        pass

class iceDecorator(drinkDecorator):
    def __init__(self, beverage):
        self.beverage = beverage
    def getName(self):
        return self.beverage.getName() + " +ice"
    def getPrice(self):
        return self.beverage.getPrice() + 0.3

class sugarDecorator(drinkDecorator):
    def __init__(self, beverage):
        self.beverage = beverage
    def getName(self):
        return self.beverage.getName() + " +sugar"
    def getPrice(self):
        return self.beverage.getPrice() + 0.5

#构建好装饰器后,在具体的业务场景中,就可以与饮料类进行关联。以可乐+冰为例,示例业务场景如下:
if  __name__=="__main__":
    coke_cola=coke()
    print("Name:%s"%coke_cola.getName())
    print("Price:%s"%coke_cola.getPrice())
    ice_coke=iceDecorator(coke_cola)
    print("Name:%s" % ice_coke.getName())
    print("Price:%s" % ice_coke.getPrice())
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 单例模式是一种软件设计模式,其目的是保证一个类只有一个实例,并提供一个全局访问点来访问这个实例。 在 Python 中,可以使用类装饰器来实现单例模式。类装饰器是一种特殊的装饰器,它可以在定义类时使用,用于修改类的行为。 下面是使用类装饰器实现单例模式的示例代码: ``` def singleton(cls): instance = None def wrapper(*args, **kwargs): nonlocal instance if instance is None: instance = cls(*args, **kwargs) return instance return wrapper @singleton class MyClass: pass ``` 在上面的代码中,`singleton` 是一个类装饰器,它接受一个类作为参数,并返回一个内部函数 `wrapper`。`wrapper` 函数检查是否已经创建了类的实例,如果没有,就创建一个新的实例,并将其保存在 `instance` 变量中。如果已经创建了实例,就直接返回该实例。 使用类装饰器实现单例模式时,可以使用 `nonlocal` 声明来修改内部函数中的局部变量,这样就可以在多次调用 `wrapper` 函数时保存类的实例。 使用类装饰器实现单例模式后,就可以像调用普通类一样调用单 ### 回答2: Python的单例模式可以通过使用类装饰器来实现。类装饰器可以在原始类上添加额外的功能,比如只实例化一个对象。 下面是一个使用类装饰器实现Python单例模式的例子: ```python def singleton(cls): instances = {} def wrapper(*args, **kwargs): if cls not in instances: instances[cls] = cls(*args, **kwargs) return instances[cls] return wrapper @singleton class MyClass: def __init__(self, x): self.x = x # 测试 obj1 = MyClass(10) obj2 = MyClass(20) # obj1 和 obj2指向同一个对象 print(obj1.x) # 输出 10 print(obj2.x) # 输出 10 print(obj1 is obj2) # 输出 True ``` 在这个例子中,我们定义了一个名为singleton的装饰器函数。singleton函数接受一个类作为参数,并返回一个新的封装函数wrapper。wrapper函数在被调用时会首先检查是否已经存在该类的实例,如果不存在则创建一个新的实例并保存在字典instances中,然后返回该实例。这样,每次创建新的对象时都会先检查是否已经有了同样类的实例,如果有则返回之前的实例,实现了单例模式。 我们的示例中,我们定义了一个名为MyClass的类,并在其上应用了singleton装饰器。这样,无论我们创建多少个MyClass的实例,它们都会指向同一个对象,因为只有第一次创建时实际上调用了MyClass的构造函数,后续创建都直接返回了之前的实例。 使用类装饰器实现Python单例模式可以简化代码,并且保证了只有一个实例存在。这对于需要限制实例数量的场景非常有用。 ### 回答3: Python的单例模式是一种设计模式,用于确保一个类只有一个实例,并提供一个全局访问点。 使用类装饰器来实现Python的单例模式是一种常见的方法。类装饰器是一个接受类作为参数并返回修改后的类的函数。 下面是一个使用类装饰器实现Python单例模式的例子: ```python def singleton(cls): instances = {} def wrapper(*args, **kwargs): if cls not in instances: instances[cls] = cls(*args, **kwargs) return instances[cls] return wrapper @singleton class MyClass: def __init__(self, name): self.name = name def say_hello(self): print("Hello, I am", self.name) # 创建实例 obj1 = MyClass("Object 1") obj2 = MyClass("Object 2") # 打印实例的名称 print(obj1.name) # Output: Object 1 print(obj2.name) # Output: Object 1 # 调用实例的方法 obj1.say_hello() # Output: Hello, I am Object 1 obj2.say_hello() # Output: Hello, I am Object 1 ``` 在上述例子中,`singleton` 是一个类装饰器函数。当我们在 `MyClass` 类上使用 `@singleton` 时,`singleton(MyClass)` 被调用并返回一个新的类 `wrapper`。在这个新的类 `wrapper` 中,我们使用 `instances` 字典来存储已经创建的实例。在 `wrapper` 的构造函数中,我们首先检查 `cls` 是否已经在 `instances` 中,如果没有,则创建一个新的实例并将其添加到 `instances` 中。最后,我们返回 `instances[cls]`,即返回已经创建的实例。 通过使用类装饰器实现Python的单例模式,我们可以确保在程序运行时只有一个实例存在,并且可以通过任何地方访问该实例

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值