Sto separando il mio software in tre livelli principali (forse livelli sarebbe un termine migliore):
- Presentazione ('Visualizzazioni')
- Logica aziendale ("Servizi" e "Archivi")
- Accesso ai dati ("Entità" (ad esempio ActiveRecords))
Che cosa ho ora?
In Presentazione, utilizzo l'accesso in sola lettura alle Entità, restituito da Archivi o Servizi, per visualizzare i dati.
$banks = $banksRegistryService->getBanksRepository()->getBanksByCity( $city );
$banksViewModel = new PaginatedList( $banks ); // some way to display banks;
// example, not real code
Trovo che questo approccio sia abbastanza efficiente in termini di prestazioni e manutenibilità del codice e comunque sicuro finché tutte le operazioni di scrittura (creazione, aggiornamento, eliminazione) sono preformate tramite Service
:
namespace Service\BankRegistry;
use Service\AbstractDatabaseService;
use Service\IBankRegistryService;
use Model\BankRegistry\Bank;
class Service
extends AbstractDatabaseService
implements IBankRegistryService
{
/**
* Registers a new Bank
*
* @param string $name Bank's name
* @param string $bik Bank's Identification Code
* @param string $correspondent_account Bank's correspondent account
*
* @return Bank
*/
public function registerBank( $name, $bik, $correspondent_account )
{
$bank = new Bank();
$bank
-> setName( $name )
-> setBik( $bik )
-> setCorrespondentAccount( $correspondent_account );
if( null === $this->getBanksRepository()->getDefaultBank() )
$this->setDefaultBank( $bank );
$this->getEntityManager()->persist( $bank );
return $bank;
}
/**
* Makes the $bank system's default bank
*
* @param Bank $bank
* @return IBankRegistryService
*/
public function setDefaultBank( Bank $bank )
{
$default_bank = $this->getBanksRepository()->getDefaultBank();
if( null !== $default_bank )
$default_bank->setDefault( false );
$bank->setDefault( true );
return $this;
}
}
Dove sono bloccato?
Ho difficoltà a come aggiornare determinati campi in Bank
Entity.
Cattiva soluzione n. 1 : creazione di una serie di setter in Service
per ogni setter in Bank
; - sembra essere abbastanza ridondante, aumenta Service
interfaccia complessità e diminuisce proporzionalmente la semplicità - qualcosa da evitare se ti interessa la padronanza del codice. Provo a seguire i principi KISS e DRY
Cattiva soluzione n. 2 : modifica di Bank
direttamente attraverso i setter nativi; - veramente male. Se avrai mai bisogno di spostare le modifiche in Service
, sarà doloroso. La logica aziendale dovrebbe rimanere nel livello della logica aziendale. Inoltre , ci sono piani per la registrazione di tutte le azioni e forse anche per le autorizzazioni degli utenti (forse attraverso i decoratori) in futuro, quindi tutte le modifiche dovrebbero essere apportate solo tramite Service
.
Possibile soluzione valida : creazione di un metodo updateBank( Bank $bank, $array_of_fields_to_update)
; - rende l'interfaccia il più semplice possibile, ma c'è un problema: uno dovrebbe non provare a impostare manualmente isDefault
flag su un banco, questa operazione dovrebbe essere eseguita attraverso il metodo setDefaultBank
. Diventa ancora peggio quando hai relazioni che non vuoi modificare direttamente.
Ovviamente, puoi semplicemente limitare i campi che possono essere modificati con questo metodo, ma come fai a dire all'utente del metodo che cosa possono e non possono modificare? Eccezioni?