Article image
Charlie Samoel
Charlie Samoel24/08/2023 07:34
Compartilhe

Exemplo em código de Singleton, Factory, Abstract factory, builder e prototype.

  • #Python

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.


Compartilhe
Comentários (0)