Além do State (Máquina de Estado), existem vários outros design patterns conhecidos. Aqui estão alguns dos mais populares, com uma breve explicação e exemplos em Python:
Garante que uma classe tenha apenas uma instância e fornece um ponto global de acesso a ela. Ideal para objetos que precisam ser únicos, como uma conexão de banco de dados.
Exemplo em Python:
class Singleton:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super(Singleton, cls).__new__(cls)
return cls._instance
singleton1 = Singleton()
singleton2 = Singleton()
print(singleton1 is singleton2) # True
Define uma interface para criar objetos, mas permite que subclasses alterem o tipo de objeto que será criado. Muito útil para criar instâncias de classes de forma flexível.
Exemplo em Python:
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def sound(self):
pass
class Dog(Animal):
def sound(self):
return "Woof!"
class Cat(Animal):
def sound(self):
return "Meow!"
class AnimalFactory:
@staticmethod
def create_animal(animal_type):
if animal_type == 'dog':
return Dog()
elif animal_type == 'cat':
return Cat()
animal = AnimalFactory.create_animal('dog')
print(animal.sound()) # Woof!
Define uma dependência um-para-muitos entre objetos, de modo que, quando um objeto muda de estado, todos os seus dependentes são notificados automaticamente.
Exemplo em Python:
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, message):
for observer in self._observers:
observer.update(message)
class Observer:
def update(self, message):
print("Observer received:", message)
subject = Subject()
observer = Observer()
subject.attach(observer)
subject.notify("Hello, Observers!") # Observer received: Hello, Observers!
Define uma família de algoritmos, encapsula cada um deles e os torna intercambiáveis. O pattern permite que o algoritmo varie independentemente dos clientes que o utilizam.
Exemplo em Python:
from abc import ABC, abstractmethod
class SortStrategy(ABC):
@abstractmethod
def sort(self, data):
pass
class QuickSort(SortStrategy):
def sort(self, data):
return sorted(data) # Placeholder for quicksort logic
class BubbleSort(SortStrategy):
def sort(self, data):
return sorted(data, reverse=True) # Placeholder for bubblesort logic
class SortContext:
def __init__(self, strategy: SortStrategy):
self._strategy = strategy
def sort(self, data):
return self._strategy.sort(data)
data = [5, 3, 8, 6]
context = SortContext(QuickSort())
print(context.sort(data)) # [3, 5, 6, 8]
Converte a interface de uma classe em outra interface que o cliente espera. O Adapter permite que classes com interfaces incompatíveis trabalhem juntas.
Exemplo em Python:
class EuropeanSocket:
def voltage(self):
return "230V"
class USSocket:
def voltage(self):
return "120V"
class USAdapter:
def __init__(self, european_socket):
self._european_socket = european_socket
def voltage(self):
return f"{self._european_socket.voltage()} adapted to 120V"
european_socket = EuropeanSocket()
adapter = USAdapter(european_socket)
print(adapter.voltage()) # 230V adapted to 120V
Esses são alguns dos principais design patterns. Cada um atende a uma situação específica no desenvolvimento de software, ajudando a manter o código modular, flexível e fácil de entender.