Curs 5 - Design Patterns în Python

Acest curs explorează cele mai utilizate design patterns în Python și exemplele lor practice.

1. Singleton

Singleton asigură că există o singură instanță a unei clase și oferă un punct global de acces la aceasta.

class Singleton:
    _instance = None
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super(Singleton, cls).__new__(cls)
        return cls._instance

s1 = Singleton()
s2 = Singleton()
print(s1 is s2)  # Output: True

2. Factory

Factory Pattern permite crearea obiectelor fără a expune logica instanțierii în codul clientului.

class Masina:
    def drive(self):
        pass

class Dacia(Masina):
    def drive(self):
        return "Conduci o Dacia."

class Tesla(Masina):
    def drive(self):
        return "Conduci o Tesla electrică."

class MasinaFactory:
    @staticmethod
    def get_masina(tip):
        if tip == "Dacia":
            return Dacia()
        elif tip == "Tesla":
            return Tesla()

m = MasinaFactory.get_masina("Tesla")
print(m.drive())  # Output: Conduci o Tesla electrică.

3. Observer

Observer permite notificarea mai multor obiecte (observatori) atunci când starea unui obiect (subiect) se schimbă.

class Subiect:
    def __init__(self):
        self._observatori = []
    
    def adauga_observator(self, observator):
        self._observatori.append(observator)
    
    def notifica(self):
        for observator in self._observatori:
            observator.update(self)

class Observator:
    def update(self, subiect):
        print("Observator notificat!")

subiect = Subiect()
obs1 = Observator()
subiect.adauga_observator(obs1)
subiect.notifica()  # Output: Observator notificat!

4. Strategy

Strategy permite schimbarea dinamică a comportamentului unui obiect prin utilizarea diferitelor strategii.

class StrategieA:
    def executa(self):
        return "Execut strategie A."

class StrategieB:
    def executa(self):
        return "Execut strategie B."

class Context:
    def __init__(self, strategie):
        self.strategie = strategie
    
    def executa_strategie(self):
        return self.strategie.executa()

c = Context(StrategieA())
print(c.executa_strategie())  # Output: Execut strategie A.
c.strategie = StrategieB()
print(c.executa_strategie())  # Output: Execut strategie B.

5. Command

Command encapsulează o cerere ca un obiect, permițând executarea acesteia mai târziu.

class Comanda:
    def executa(self):
        pass

class ComandaSalut(Comanda):
    def executa(self):
        print("Salut!")

class Invocator:
    def __init__(self):
        self.comenzi = []
    
    def adauga_comanda(self, comanda):
        self.comenzi.append(comanda)
    
    def executa_comenzi(self):
        for comanda in self.comenzi:
            comanda.executa()

invocator = Invocator()
invocator.adauga_comanda(ComandaSalut())
invocator.executa_comenzi()  # Output: Salut!

Resurse suplimentare: