Exemplo em código de Singleton, Factory, Abstract factory, builder e prototype.
Aprofundando os estudos em desgin patterns no grupo padrão de criação.
Singleton:
O padrão Singleton garante que uma classe tenha apenas uma instância e fornece um ponto global de acesso a essa instância.
class Singleton:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
# Uso do Singleton
instance1 = Singleton()
instance2 = Singleton()
print(instance1 == instance2) # True, pois é a mesma instância
Factory Method:
O padrão Factory Method define uma interface para criar objetos, mas permite que as subclasses decidam qual classe concreta instanciar.
from abc import ABC, abstractmethod
class Product(ABC):
@abstractmethod
def operation(self):
pass
class ConcreteProductA(Product):
def operation(self):
return "ConcreteProductA"
class ConcreteProductB(Product):
def operation(self):
return "ConcreteProductB"
class Creator(ABC):
@abstractmethod
def factory_method(self):
pass
def some_operation(self):
product = self.factory_method()
return f"Creator: {product.operation()}"
class ConcreteCreatorA(Creator):
def factory_method(self):
return ConcreteProductA()
class ConcreteCreatorB(Creator):
def factory_method(self):
return ConcreteProductB()
# Uso do Factory Method
creator_a = ConcreteCreatorA()
print(creator_a.some_operation()) # Output: "Creator: ConcreteProductA"
creator_b = ConcreteCreatorB()
print(creator_b.some_operation()) # Output: "Creator: ConcreteProductB"
Abstract Factory:
O padrão Abstract Factory fornece uma interface para criar famílias de objetos relacionados sem especificar suas classes concretas.
from abc import ABC, abstractmethod
class AbstractProductA(ABC):
@abstractmethod
def operation(self):
pass
class AbstractProductB(ABC):
@abstractmethod
def operation(self):
pass
class ConcreteProductA1(AbstractProductA):
def operation(self):
return "ConcreteProductA1"
class ConcreteProductA2(AbstractProductA):
def operation(self):
return "ConcreteProductA2"
class ConcreteProductB1(AbstractProductB):
def operation(self):
return "ConcreteProductB1"
class ConcreteProductB2(AbstractProductB):
def operation(self):
return "ConcreteProductB2"
class AbstractFactory(ABC):
@abstractmethod
def create_product_a(self):
pass
@abstractmethod
def create_product_b(self):
pass
class ConcreteFactory1(AbstractFactory):
def create_product_a(self):
return ConcreteProductA1()
def create_product_b(self):
return ConcreteProductB1()
class ConcreteFactory2(AbstractFactory):
def create_product_a(self):
return ConcreteProductA2()
def create_product_b(self):
return ConcreteProductB2()
# Uso do Abstract Factory
factory1 = ConcreteFactory1()
product_a = factory1.create_product_a()
product_b = factory1.create_product_b()
print(product_a.operation()) # Output: "ConcreteProductA1"
print(product_b.operation()) # Output: "ConcreteProductB1"
Builder:
O padrão Builder separa a construção de um objeto complexo de sua representação, permitindo a criação de diferentes representações do mesmo objeto.
class Product:
def __init__(self):
self.parts = []
def add_part(self, part):
self.parts.append(part)
def list_parts(self):
return ", ".join(self.parts)
class Builder:
def build_part_a(self):
pass
def build_part_b(self):
pass
class ConcreteBuilder1(Builder):
def build_part_a(self):
return "PartA1"
def build_part_b(self):
return "PartB1"
class ConcreteBuilder2(Builder):
def build_part_a(self):
return "PartA2"
def build_part_b(self):
return "PartB2"
class Director:
def __init__(self):
self.builder = None
def set_builder(self, builder):
self.builder = builder
def construct(self):
product = Product()
product.add_part(self.builder.build_part_a())
product.add_part(self.builder.build_part_b())
return product
# Uso do Builder
director = Director()
builder1 = ConcreteBuilder1()
director.set_builder(builder1)
product1 = director.construct()
builder2 = ConcreteBuilder2()
director.set_builder(builder2)
product2 = director.construct()
print(product1.list_parts()) # Output: "PartA1, PartB1"
print(product2.list_parts()) # Output: "PartA2, PartB2"
Prototype:
O padrão Prototype cria novos objetos duplicando um objeto existente (protótipo) em vez de criar do zero.
import copy
class Prototype:
def clone(self):
pass
class ConcretePrototype(Prototype):
def __init__(self, value):
self.value = value
def clone(self):
return copy.deepcopy(self)
# Uso do Prototype
prototype = ConcretePrototype(1)
clone = prototype.clone()
print(clone.value) # Output: 1
Esses exemplos são simplificados para ilustrar os conceitos de cada padrão. Em cenários mais complexos, os padrões podem ter usos mais sofisticados e vantagens adicionais.