Python Design Pattern

Panoramica

Lo sviluppo di software moderno deve soddisfare requisiti aziendali complessi. Deve inoltre tenere conto di fattori come la futura estensibilità e manutenibilità. Una buona progettazione di un sistema software è fondamentale per raggiungere questi obiettivi. I modelli di progettazione giocano un ruolo importante in tali sistemi.

Per comprendere il modello di progettazione, consideriamo l'esempio seguente:

  • Il design di ogni auto segue un modello di progettazione di base, quattro ruote, volante, il sistema di trasmissione principale come acceleratore-freno-frizione, ecc.

Quindi, tutte le cose costruite / prodotte ripetutamente, devono inevitabilmente seguire uno schema nel suo design ... automobili, biciclette, pizze, bancomat, qualunque cosa ... anche il tuo divano letto.

Disegni che sono diventati quasi un modo standard di codificare una logica / meccanismo / tecnica nel software, quindi sono conosciuti o studiati come Software Design Patterns.

Perché Design Pattern è importante?

I vantaggi dell'utilizzo di Design Patterns sono:

  • Ti aiuta a risolvere problemi di progettazione comuni attraverso un approccio collaudato.

  • Nessuna ambiguità nella comprensione in quanto ben documentate.

  • Riduci il tempo di sviluppo complessivo.

  • Ti aiuta a gestire estensioni e modifiche future con più facilità che altrimenti.

  • Possono ridurre gli errori nel sistema poiché sono soluzioni comprovate a problemi comuni.

Classificazione dei modelli di design

I modelli di design GoF (Gang of Four) sono classificati in tre categorie: creazionale, strutturale e comportamentale.

Modelli creazionali

I modelli di progettazione di creazione separano la logica di creazione degli oggetti dal resto del sistema. Invece di creare oggetti, i modelli creazionali li creano per te. I modelli creativi includono Abstract Factory, Builder, Factory Method, Prototype e Singleton.

I modelli di creazione non sono comunemente usati in Python a causa della natura dinamica del linguaggio. Anche il linguaggio stesso ci fornisce tutta la flessibilità di cui abbiamo bisogno per creare in modo sufficientemente elegante, raramente abbiamo bisogno di implementare qualcosa sopra, come singleton o Factory.

Inoltre, questi modelli forniscono un modo per creare oggetti nascondendo la logica di creazione, piuttosto che istanziare gli oggetti direttamente utilizzando un nuovo operatore.

Modelli strutturali

A volte invece di iniziare da zero, è necessario costruire strutture più grandi utilizzando un insieme di classi esistente. È qui che i modelli di classe strutturale usano l'ereditarietà per costruire una nuova struttura. I modelli di oggetti strutturali utilizzano la composizione / aggregazione per ottenere una nuova funzionalità. Adapter, Bridge, Composite, Decorator, Façade, Flyweight e Proxy sono modelli strutturali. Offrono i modi migliori per organizzare la gerarchia di classe.

Modelli comportamentali

I modelli comportamentali offrono i modi migliori per gestire la comunicazione tra gli oggetti. I modelli rientrano in queste categorie sono: Visitatore, Catena di responsabilità, Comando, Interprete, Iteratore, Mediatore, Memento, Osservatore, Stato, Strategia e Metodo modello sono modelli comportamentali.

Poiché rappresentano il comportamento di un sistema, vengono generalmente utilizzati per descrivere la funzionalità dei sistemi software.

Modelli di design comunemente usati

Singleton

È uno dei modelli di design più controversi e famosi. Viene utilizzato in linguaggi eccessivamente orientati agli oggetti ed è una parte vitale della tradizionale programmazione orientata agli oggetti.

Il pattern Singleton viene utilizzato per,

  • Quando è necessario implementare la registrazione. L'istanza del logger è condivisa da tutti i componenti del sistema.

  • I file di configurazione lo utilizzano perché la cache delle informazioni deve essere mantenuta e condivisa da tutti i vari componenti del sistema.

  • Gestione di una connessione a un database.

Ecco il diagramma UML,

class Logger(object):
   def __new__(cls, *args, **kwargs):
      if not hasattr(cls, '_logger'):
      cls._logger = super(Logger, cls).__new__(cls, *args, **kwargs)
return cls._logger

In questo esempio, Logger è un Singleton.

Quando viene chiamato __new__, normalmente costruisce una nuova istanza di quella classe. Quando lo sovrascriviamo, controlliamo prima se la nostra istanza singleton è stata creata o meno. In caso contrario, lo creiamo utilizzando una super chiamata. Pertanto, ogni volta che chiamiamo il costruttore su Logger, otteniamo sempre la stessa identica istanza.

>>>
>>> obj1 = Logger()
>>> obj2 = Logger()
>>> obj1 == obj2
True
>>>
>>> obj1
<__main__.Logger object at 0x03224090>
>>> obj2
<__main__.Logger object at 0x03224090>