Here are some examples of design patterns in Python:
Factory Pattern
class Shape:
def draw(self):
pass
class Circle(Shape):
def draw(self):
print("Drawing a circle")
class Rectangle(Shape):
def draw(self):
print("Drawing a rectangle")
class ShapeFactory:
def get_shape(self, shape_type: str):
if shape_type == 'circle':
return Circle()
elif shape_type == 'rectangle':
return Rectangle()
else:
raise ValueError('Invalid shape type')
In the above example, ShapeFactory creates objects of Circle or Rectangle based on the input parameter shape_type.
Observer Pattern
The Observer pattern is used to establish a one-to-many dependency between objects. When the state of one object changes, all its dependents are notified and updated automatically.
class Subject:
def __init__(self):
self.observers = []
def attach(self, observer):
self.observers.append(observer)
def detach(self, observer):
self.observers.remove(observer)
def notify(self):
for observer in self.observers:
observer.update(self)
class Observer:
def update(self, subject):
pass
class ConcreteObserver(Observer):
def update(self, subject):
print('Subject state has changed:', subject.state)
class ConcreteSubject(Subject):
def __init__(self):
super().__init__()
self.state = None
def set_state(self, state):
self.state = state
self.notify()
In the above example, Subject maintains a list of Observer objects and notifies them when its...
class Subject:
def __init__(self):
self.observers = []
self.state = None
def attach(self, observer):
self.observers.append(observer)
def detach(self, observer):
self.observers.remove(observer)
def notify(self):
for observer in self.observers:
observer.update(self.state)
def set_state(self, state):
self.state = state
self.notify()
class Observer:
def update(self, state):
pass
class ConcreteObserverA(Observer):
def update(self, state):
print(f'ConcreteObserverA received state: {state}')
class ConcreteObserverB(Observer):
def update(self, state):
print(f'ConcreteObserverB received state: {state}')
In the above example, Subject is a class that maintains a list of Observer objects and notifies them when its state changes. attach and detach methods are used to add and remove observers from the list. notify method iterates over the list of observers and calls their update method with the current state. set_state method sets the current state of the subject and calls notify to update all observers.
Observer is an abstract class that defines the interface for objects that should be notified when the subject changes. ConcreteObserverA and ConcreteObserverB inherit from Observer and implement the update method to define their own behavior when notified.
Here is an example of how to use the Observer pattern:
subject = Subject()
observer_a = ConcreteObserverA()
observer_b = ConcreteObserverB()
subject.attach(observer_a)
subject.attach(observer_b)
subject.set_state('new state')
# Output:
# ConcreteObserverA received state: new state
# ConcreteObserverB received state: new state
subject.detach(observer_b)
subject.set_state('another state')
# Output:
# ConcreteObserverA received state: another state
In the above example, we create a Subject object and two observers, ConcreteObserverA and ConcreteObserverB. We attach both observers to the subject and then change its state using set_state. Both observers are notified and print the new state. We then detach ConcreteObserverB from the subject and change its state again. Only ConcreteObserverA is notified this time.
Singleton Pattern
class Singleton:
__instance = None
def __new__(cls):
if cls.__instance is None:
cls.__instance = super().__new__(cls)
return cls.__instance
In the above example, Singleton is a class that can only have one instance. The __new__ method ensures that if an instance of Singleton already exists, it will return that instance instead of creating a new one.
Decorator Pattern
class Component:
def operation(self):
pass
class ConcreteComponent(Component):
def operation(self):
print('ConcreteComponent operation')
class Decorator(Component):
def __init__(self, component: Component):
self.component = component
def operation(self):
self.component.operation()
class ConcreteDecoratorA(Decorator):
def operation(self):
super().operation()
print('ConcreteDecoratorA operation')
class ConcreteDecoratorB(Decorator):
def operation(self):
super().operation()
print('ConcreteDecoratorB operation')
In the above example, Component is an interface that defines the base functionality of an object. ConcreteComponent implements the interface. Decorator is an abstract class that implements the same interface and holds a reference to a Component. ConcreteDecoratorA and ConcreteDecoratorB inherit from Decorator and add their own functionality to the base operation.
Strategy Pattern
class Strategy:
def execute(self):
pass
class ConcreteStrategyA(Strategy):
def execute(self):
print('Executing ConcreteStrategyA')
class ConcreteStrategyB(Strategy):
def execute(self):
print('Executing ConcreteStrategyB')
class Context:
def __init__(self, strategy: Strategy):
self.strategy = strategy
def execute_strategy(self):
self.strategy.execute()
In the above example, Strategy is an interface that defines the algorithm that will be used by the Context object. ConcreteStrategyA and ConcreteStrategyB implement the interface with different algorithms. Context holds a reference to a Strategy object and executes its algorithm using execute_strategy.
In the above example, AbstractClass is an abstract class that defines a template method that calls two abstract methods, operation1 and operation2. ConcreteClassA and ConcreteClassB inherit from AbstractClass and implement the abstract methods to define their own behavior.