Immagina di voler dipingere una stanza. Sei il proprietario di questa stanza e un Painter
è in grado di dipingere la stanza. Esistono diversi tipi di Painters
: a BluePainter
, a RedPainter
ecc. Per ogni colore esiste un Painter
! Non ti interessa in quale colore verrà dipinta la stanza, purché la stanza venga dipinta. Questa è una situazione di modello strategico.
(A proposito, so che ha più senso avere diversi tipi di Colors
e dare Paint
o Painter
a Color
istanza, ma usiamo il mio esempio dove ogni tipo di Painter
è solo in grado di dipingere un colore.)
Ci sono due modi generali per dipingere la mia stanza. Illustrerò entrambi questi modi in due diverse situazioni.
Nella prima situazione, l'istanza Painter
non richiede alcun parametro.
Opzione 1: ti è stata fornita un'istanza Painter
che hai detto $painter->paintRoom()
. Il Painter
quindi va e dipinge la stanza.
Si potrebbe dire che Painter
non ha stato ed è un'istanza di una classe Helper
.
Opzione 2: ti è stata fornita un'istanza PainterFactory
che dici a $painter_factory->createPainter()->paintRoom()
. Il Painter
quindi va e dipinge la stanza.
In questa situazione il PainterFactory
è quello senza stato ed è in istanza di una classe Helper
. Vedremo perché Painter
avrà lo stato nella prossima situazione.
Nella seconda situazione, l'istanza di Painter
richiede un parametro. A Painter
è istanziato da: new Painter(paint_thickness)
. Lo spessore della vernice determina quanto devono essere spessi gli strati di vernice sulle pareti.
Opzione1: ti è stata fornita un'istanza Painter
che hai detto $painter->paintRoom(paint_thickness)
. Il Painter
quindi va e dipinge la stanza. Immagina che Painter
sia solo certificato / in grado di applicare la vernice di un certo spessore.
È più ovvio ora che Painter
è una classe Helper
.
Opzione 2: ti è stata fornita un'istanza PainterFactory
che dici a $painter_factory->createPainter(paint_depth)->paintRoom()
. Il Painter
quindi va e dipinge la stanza.
In questa situazione, PainterFactory
rimane la classe Helper
. Il Painter
avrà lo stato: contiene una proprietà paint_thickness
. Painter
non è una classe Helper
per questa opzione.
Il motivo per cui penso che Painter
sia una classe Helper
nella prima situazione e PainterFactory
è una classe Helper
nella seconda situazione è che non sarà mai necessario avere più di una istanza di una Painter
class.
Per riassumere: è spesso possibile utilizzare una sola istanza di una classe per determinate funzionalità o riscrivere la classe per contenere effettivamente lo stato. La prima opzione rappresenta l'utilizzo delle classi Helper
. Le classi Helper
sono spesso criticate come di natura procedurale e statica e quindi cattive in OOP e un potenziale debito tecnico.
Tuttavia, la creazione di istanze di oggetti che hanno uno stato deve avvenire attraverso un Helper
di fabbrica (come abbiamo visto nell'esempio) o mediante l'istanziazione diretta. Dato che Helper
factory è ancora un Helper
, sembra che l'uso delle classi Helper
non sia ancora completamente evitato - e l'istanziazione diretta è essenzialmente di natura statica.
Quindi la mia domanda è: le classi Helper
sono davvero negative? Si dovrebbe favorire un oggetto con stato su un oggetto senza stato ma con comportamento? Ma ripeto, che dire degli oggetti piccoli che non hanno un comportamento diverso dal comportamento che esiste nel loro unico metodo (ad esempio, immagina di riscrivere una grande classe% co_de chiamata Helper
in classi separate come Math
, Multiplication
, Addition
ecc.).
Quali sono alcune buone regole generali per scegliere un'opzione in una situazione Division
?