Scrivo spesso applicazioni intensive di database e ho scoperto il modello di gateway che sembrava adattarsi alle mie esigenze. Il mio problema ora è che molti dei miei modelli sono composti da altri modelli.
Ad esempio, ho un modello User
e un modello Order
ciascuno con un proprio Gateway
.
Interfaccia per User
Gateway:
interface IUserGateway {
public function create(User $user) : User;
public function query($limit = -1, $offset = 0) : Array;
public function update(User $user) : User;
public function delete(User $user) : boolean;
public function findById(int $id) : User;
}
Interfaccia per Order
Gateway:
interface IOrderGateway {
public function create(Order $user) : Order;
public function query($limit = -1, $offset = 0) : Array;
public function update(Order $user) : Order;
public function delete(Order $user) : boolean;
public function findById(int $id) : Order;
}
Ora Order
contiene un'istanza di User
che viene quindi referenziata all'interno del mio database con un indice estero orders.user_id
all'interno della tabella orders
.
La domanda ora è come interrogare e creare gli oggetti all'interno dell'implementazione IOrderGateway
.
Fino ad ora ho usato Dependency Injection
per iniettare IUserGateway
istanze nella constructor
della mia implementazione IOrderGateway
e quindi chiamare IUserGateway::findById
per ottenere l'istanza User
richiesta per ogni Order
.
Ma questo mi sembra uno spreco di risorse perché devo fare una query aggiuntiva al database (MySQL in questo caso) che potrebbe anche essere eseguita da un INNER JOIN
.
Ma poi IOrderGateway
deve preoccuparsi della creazione di User
s.
Ho anche fatto qualche ricerca in più e ho trovato implementazioni di Gateway Pattern
che restituiscono solo i dati di riga non elaborati dal livello dati e poi li passiamo a Factory
che crea l'oggetto.
Quindi quale metodo dovrei usare? Ci sono soluzioni migliori di quelle menzionate?
Quando non utilizzo un JOIN
, ho solo il user_id
per ogni ordine. Per ottenere l'istanza dell'utente devo chiamare IUserGateway::findById()
per ottenere quell'istanza che causa una query aggiuntiva al database.
Il problema è che non so quale soluzione usare. Sono relativamente nuovo a OO-Concepts. Per me usare JOIN
per interrogare e quindi istanziare Order
e User
sembra essere la soluzione migliore. Ma poi violerei i principi SOLID
perché IOrderGateway
si preoccupa di Order
e User
.