-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdecorator.py
More file actions
105 lines (70 loc) · 2.44 KB
/
decorator.py
File metadata and controls
105 lines (70 loc) · 2.44 KB
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
"""
Decorator Design Pattern
The Decorator pattern allows behavior to be added to individual objects dynamically
without affecting the behavior of other objects from the same class.
Use cases:
- Adding features to objects without modifying their structure
- When subclassing would be impractical (too many combinations)
- Runtime feature addition
"""
from abc import ABC, abstractmethod
# Component interface
class Coffee(ABC):
"""Abstract component."""
@abstractmethod
def cost(self):
"""Get cost of coffee."""
pass
@abstractmethod
def description(self):
"""Get description of coffee."""
pass
# Concrete component
class SimpleCoffee(Coffee):
"""Concrete component."""
def cost(self):
return 5
def description(self):
return "Simple coffee"
# Base decorator
class CoffeeDecorator(Coffee):
"""Base decorator class."""
def __init__(self, coffee):
self._coffee = coffee
def cost(self):
return self._coffee.cost()
def description(self):
return self._coffee.description()
# Concrete decorators
class MilkDecorator(CoffeeDecorator):
"""Concrete decorator: Milk."""
def cost(self):
return self._coffee.cost() + 2
def description(self):
return self._coffee.description() + ", Milk"
class SugarDecorator(CoffeeDecorator):
"""Concrete decorator: Sugar."""
def cost(self):
return self._coffee.cost() + 1
def description(self):
return self._coffee.description() + ", Sugar"
class WhipDecorator(CoffeeDecorator):
"""Concrete decorator: Whip."""
def cost(self):
return self._coffee.cost() + 3
def description(self):
return self._coffee.description() + ", Whip"
# Example usage
if __name__ == "__main__":
# Simple coffee
coffee = SimpleCoffee()
print(f"{coffee.description()}: ${coffee.cost()}")
# Coffee with milk
coffee_with_milk = MilkDecorator(SimpleCoffee())
print(f"{coffee_with_milk.description()}: ${coffee_with_milk.cost()}")
# Coffee with milk and sugar
coffee_full = SugarDecorator(MilkDecorator(SimpleCoffee()))
print(f"{coffee_full.description()}: ${coffee_full.cost()}")
# Coffee with everything
coffee_deluxe = WhipDecorator(SugarDecorator(MilkDecorator(SimpleCoffee())))
print(f"{coffee_deluxe.description()}: ${coffee_deluxe.cost()}")