Sto osservando questo esempio
Estratto pertinente dall'alto:
class AlbumController
{
public function getAlbumTable()
{
if (!$this->albumTable) {
$sm = $this->getServiceLocator();
//* My Question Lies Here:
$this->albumTable = $sm->get('Album\Model\AlbumTable');
}
return $this->albumTable;
}
}
Che cos'è $this->albumTable
? Il suo tipo è AlbumTable
. Cos'è AlbumTable
? È una classe che gestisce un'istanza di class TableGateway
del modulo ZendDb di ZF2.
Il problema
In un certo senso, AlbumController
dipende su TableGateway
. ServiceLocator rende solo questa catena di dipendenze leggermente più nascosta.
In realtà rende $this->albumTable
come una "variabile che contiene dati" e aggiunge la possibilità di "chiamare quella variabile da qualsiasi parte all'interno del codice per un capriccio" - tipo di dichiarare un tipo di dati int
, dichiarare TableGateway
legato alla tua stessa entità, insieme alla possibilità di aggiungere le tue personali funzioni di accesso e recupero dati aziendali. Concedo che è abbastanza bello ...
E allora? Qual è il mio problema con questo?
Problema: la classe AlbumController
contiene la dipendenza su TableGateway
.
Volevo cercare maggiori chiarimenti sul perché questo sia accettabile in termini di Principio di Responsabilità Unica e altri simili problemi di separazione OO. Forse sto prendendo un po 'di distanza, ma tutti i bisogni di AlbumController sono i dati che TableGateway può fornire, vale a dire cose come i dati di tipo Album()
. Perché non implementare un meccanismo che può ottenere AlbumController
dei suoi dati ma senza la dipendenza indiretta da TableGateway? Esistono schemi di progettazione che possono farlo accadere.
Per riepilogare
- Perché tollerare la dipendenza da TableGateway nella classe Controller?
- Come è nato ServiceLocator - è apparentemente abituato a "mettere la dipendenza il più lontano possibile pur mantenendola lì". È questo lo scopo di
SeviceLocator
? - Perché non utilizzare altre strutture OO (fabbriche, costruttori, ecc.) per fornire / popolare il controllore direttamente con i dati di cui ha bisogno (cioè
Album
), invece di appesantirlo conTableGateway
?
Spirito della domanda
Qual è lo scopo di ServiceLocator Pattern? Perché è lì perché è necessario quale problema risolve veramente, quando sembra che semplicemente spinga via le dipendenze?
Inoltre, ServiceLocator è una dipendenza in ogni controller ZF2 che estende AbstractController ... Così facendo il nostro AlbumController personalizzato dipende da ServiceLocator e da qualsiasi cosa che ServiceLocator decide di chiamare (ad esempio TableGateway). Puoi quindi chiamare qualsiasi servizio che ti interessa da qualsiasi postazione di controller che desideri. Che cosa è successo all'iniezione di dipendenza e all'inversione dei concetti di controllo?
UPDATE:
Sembra che Zend abbia deprecato ServiceManager::getServiceLocator()
dalla versione 3.0.0. Raccomanda di "usare il contenitore passato in fabbrica".
Vedi anche questo post sul blog sulla deprecazione di ServiceLocatorAware