The Singleton pattern ensures that a class has only one instance and provides a global point of access to it.
def singleton(cls):
instances = {}
def get_instance():
if cls not in instances:
instances[cls] = cls()
return instances[cls]
return get_instance
@singleton
class SingletonClass:
def __init__(self):
print("Singleton instance created")
# Usage:
instance1 = SingletonClass() # Output: Singleton instance created
instance2 = SingletonClass()
print(instance1 is instance2) # Output: True (same instance)
__new__
method:class Singleton:
_instance = None
def __new__(cls):
if not cls._instance:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self):
print("Singleton instance created")
# Usage:
instance1 = Singleton() # Output: Singleton instance created
instance2 = Singleton()
print(instance1 is instance2) # Output: True (same instance)
The Factory pattern and Abstract Factory pattern are creational patterns that provide interfaces for creating objects without specifying their concrete classes.
class Shape:
def draw(self):
pass
class Circle(Shape):
def draw(self):
print("Circle.draw")
class Square(Shape):
def draw(self):
print("Square.draw")
class ShapeFactory:
def create_shape(self, shape_type):
if shape_type == 'circle':
return Circle()
elif shape_type == 'square':
return Square()
else:
raise ValueError("Unknown shape type")
# Usage:
factory = ShapeFactory()
circle = factory.create_shape('circle')
circle.draw() # Output: Circle.draw
class AbstractFactory:
def create_shape(self):
pass
class CircleFactory(AbstractFactory):
def create_shape(self):
return Circle()
class SquareFactory(AbstractFactory):
def create_shape(self):
return Square()
# Usage:
factory = CircleFactory()
circle = factory.create_shape()
circle.draw() # Output: Circle.draw
The Observer pattern and Strategy pattern are behavioral patterns that define a way to communicate changes and select algorithms at runtime, respectively.
class Observer:
def update(self, message):
pass
class Subject:
def __init__(self):
self._observers = []
def add_observer(self, observer):
self._observers.append(observer)
def notify_observers(self, message):
for observer in self._observers:
observer.update(message)
# Usage:
class ConcreteObserver(Observer):
def update(self, message):
print(f"Received message: {message}")
subject = Subject()
observer1 = ConcreteObserver()
observer2 = ConcreteObserver()
subject.add_observer(observer1)
subject.add_observer(observer2)
subject.notify_observers("Hello observers!") # Output: Received message: Hello observers!
class Strategy:
def execute(self):
pass
class ConcreteStrategyA(Strategy):
def execute(self):
print("Executing strategy A")
class ConcreteStrategyB(Strategy):
def execute(self):
print("Executing strategy B")
class Context:
def __init__(self, strategy):
self._strategy = strategy
def execute_strategy(self):
self._strategy.execute()
# Usage:
context = Context(ConcreteStrategyA())
context.execute_strategy() # Output: Executing strategy A
context = Context(ConcreteStrategyB())
context.execute_strategy() # Output: Executing strategy B