Creational design patterns deal with object creation mechanisms. They aim to reduce the complexity and instability caused by creating objects directly using the new operator or class constructors. These patterns provide various object creation approaches that increase flexibility and reuse of existing code.
Python, being a dynamic and flexible language, provides various ways to implement creational patterns effectively. Understanding these patterns allows developers to write modular, scalable, and testable code.
Common creational patterns include:
The Singleton pattern ensures that a class has only one instance and provides a global point of access to it.
class Singleton:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super(Singleton, cls).__new__(cls)
return cls._instance
obj1 = Singleton()
obj2 = Singleton()
print(obj1 is obj2) # True
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 Logger:
def log(self, msg):
print(msg)
log1 = Logger()
log2 = Logger()
print(log1 is log2) # True
The Factory Method pattern defines an interface for creating an object, but allows subclasses to alter the type of objects that will be created.
class Animal:
def speak(self):
pass
class Dog(Animal):
def speak(self):
return "Woof!"
class Cat(Animal):
def speak(self):
return "Meow!"
class AnimalFactory:
def create_animal(self, animal_type):
if animal_type == "dog":
return Dog()
elif animal_type == "cat":
return Cat()
factory = AnimalFactory()
animal = factory.create_animal("dog")
print(animal.speak()) # Woof!
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def speak(self):
pass
class Dog(Animal):
def speak(self):
return "Woof!"
class Cat(Animal):
def speak(self):
return "Meow!"
class AnimalFactory(ABC):
@abstractmethod
def create_animal(self):
pass
class DogFactory(AnimalFactory):
def create_animal(self):
return Dog()
class CatFactory(AnimalFactory):
def create_animal(self):
return Cat()
factory = DogFactory()
animal = factory.create_animal()
print(animal.speak()) # Woof!
The Abstract Factory pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes.
class Dog:
def speak(self):
return "Woof!"
class Cat:
def speak(self):
return "Meow!"
class WildDog:
def speak(self):
return "Grrr!"
class WildCat:
def speak(self):
return "Roar!"
class PetFactory:
def create_dog(self):
return Dog()
def create_cat(self):
return Cat()
class WildFactory:
def create_dog(self):
return WildDog()
def create_cat(self):
return WildCat()
def get_animals(factory):
dog = factory.create_dog()
cat = factory.create_cat()
print(dog.speak())
print(cat.speak())
get_animals(PetFactory()) # Woof!, Meow!
get_animals(WildFactory()) # Grrr!, Roar!
The Builder pattern separates the construction of a complex object from its representation, so the same construction process can create different representations.
class Pizza:
def __init__(self):
self.ingredients = []
def add_ingredient(self, ingredient):
self.ingredients.append(ingredient)
def show(self):
print("Pizza with:", ", ".join(self.ingredients))
class PizzaBuilder:
def __init__(self):
self.pizza = Pizza()
def add_cheese(self):
self.pizza.add_ingredient("cheese")
return self
def add_pepperoni(self):
self.pizza.add_ingredient("pepperoni")
return self
def add_olives(self):
self.pizza.add_ingredient("olives")
return self
def build(self):
return self.pizza
builder = PizzaBuilder()
pizza = builder.add_cheese().add_pepperoni().add_olives().build()
pizza.show()
The Prototype pattern creates new objects by copying an existing object, known as the prototype. It is used when object creation is costly or complex.
import copy
class Car:
def __init__(self, model, color):
self.model = model
self.color = color
def __str__(self):
return f"{self.color} {self.model}"
car1 = Car("Sedan", "Red")
car2 = copy.deepcopy(car1)
car2.color = "Blue"
print(car1) # Red Sedan
print(car2) # Blue Sedan
class PrototypeRegistry:
def __init__(self):
self._items = {}
def register(self, name, obj):
self._items[name] = obj
def clone(self, name, **attrs):
obj = copy.deepcopy(self._items[name])
obj.__dict__.update(attrs)
return obj
registry = PrototypeRegistry()
original = Car("SUV", "Black")
registry.register("black_suv", original)
cloned = registry.clone("black_suv", color="White")
print(cloned)
| Pattern | Purpose | When to Use |
|---|---|---|
| Singleton | Ensure only one instance exists | Global configuration, logging |
| Factory Method | Delegate instantiation to subclass | Let subclasses decide instantiation |
| Abstract Factory | Create families of objects | Systems with multiple object families |
| Builder | Construct complex objects | Many optional fields or steps |
| Prototype | Clone existing objects | Object creation is expensive |
While Singleton offers global access, overuse may lead to tightly coupled code. Use with care.
Factory and Abstract Factory help isolate creation logic, making code easier to test and maintain.
Builder improves code readability and maintainability for objects with many parameters or steps.
For performance-critical applications, cloning objects using Prototype is faster than rebuilding.
Creational design patterns in Python play a crucial role in object construction. They promote flexibility and reduce coupling by separating object creation from its usage. Whether you are working with a configuration manager, a game engine, or a web application, these patterns enable scalable and maintainable code.
Understanding and correctly implementing Singleton, Factory, Abstract Factory, Builder, and Prototype patterns allows you to construct objects systematically and cleanly. These patterns are fundamental building blocks in software architecture and essential knowledge for every Python developer.
Python is commonly used for developing websites and software, task automation, data analysis, and data visualisation. Since it's relatively easy to learn, Python has been adopted by many non-programmers, such as accountants and scientists, for a variety of everyday tasks, like organising finances.
Learning Curve: Python is generally considered easier to learn for beginners due to its simplicity, while Java is more complex but provides a deeper understanding of how programming works.
The point is that Java is more complicated to learn than Python. It doesn't matter the order. You will have to do some things in Java that you don't in Python. The general programming skills you learn from using either language will transfer to another.
Read on for tips on how to maximize your learning. In general, it takes around two to six months to learn the fundamentals of Python. But you can learn enough to write your first short program in a matter of minutes. Developing mastery of Python's vast array of libraries can take months or years.
6 Top Tips for Learning Python
The following is a step-by-step guide for beginners interested in learning Python using Windows.
Best YouTube Channels to Learn Python
Write your first Python programStart by writing a simple Python program, such as a classic "Hello, World!" script. This process will help you understand the syntax and structure of Python code.
The average salary for Python Developer is ₹5,55,000 per year in the India. The average additional cash compensation for a Python Developer is within a range from ₹3,000 - ₹1,20,000.
Copyrights © 2024 letsupdateskills All rights reserved