Skip to content

Instantly share code, notes, and snippets.

@rg3915
Created October 27, 2024 04:14
Show Gist options
  • Save rg3915/9d4afc17f6fb83f4e51b0db07b534cb3 to your computer and use it in GitHub Desktop.
Save rg3915/9d4afc17f6fb83f4e51b0db07b534cb3 to your computer and use it in GitHub Desktop.
Design Patterns in Python

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:

1. Singleton

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

2. Factory Method

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!

3. Observer

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!

4. Strategy

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]

5. Adapter

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment