Ho un codice che accoppia strettamente il codice specifico del prodotto e il codice di accesso al prodotto. Non sono sicuro di come districarlo. Ad esempio, per testare Prodotto, devo prendere in giro gli oggetti Access. E forse non c'è modo di aggirarlo, ma forse c'è. Ho un codice che va in questo modo:
class Product
{
function __construct() {
global $user; //current logged in user object
$id = $user->getId(); //used to make calls to DB
$this->access = $db->query("SELECT access ... where id=$id");
//DB returns "product access" information which is used to allow/reject access
//code of product is tightly coupled with code for authorization
}
}
class ProductA extends Product
{
function __construct() {
parent::__construct();
if ($this->access != "all_access") doPartialAccess();
else doFullAccess();
}
}
//...
class ProductX extends Product
{
function __construct() {
parent::__construct();
if ($this->access != "all_access") doPartialAccess();
else doFullAccess();
}
}
Approccio 1
Il mio primo pensiero è usare injection injection , per iniettare $user
(o $access
object direttamente) nel costruttore di Product
. ma aspetta ... Dovrò farlo con ogni Product*
estendendo Product
. Anche se lo faccio, sarà effettivamente sufficiente spostare l'istanziazione di $user
altrove nel codice (al di fuori delle classi Product*
). Come tale, non sono sicuro che sarà la soluzione migliore, perché ritengo che convolli il codice con l'introduzione di quelli che ritengo siano parametri non necessari nei costruttori, invece di rendere il codice base più gestibile.
Approccio 2
Un altro pensiero è di avere una sorta di "registro" per l'oggetto di accesso, in cui posso inserire oggetti e estrarre gli oggetti da esso. Ma aspetta, il modello di registro è considerato un anti-modello. E lo sto già usando - vedi global $user
!? Non un modo orientato agli oggetti per farlo, bada bene, ma il concetto di registro tuttavia.
Domanda
Il mio obiettivo a lungo termine è quello di disaccoppiare il codice prodotto (vari calcoli, assemblare una stringa del modello di prodotto, ecc.) dal codice dei permessi utente che controlla l'accesso alla classe. I costrutti di accesso al prodotto sono effettivamente utilizzati per creare alcune query SQL, quindi il codice di prodotto e accesso è praticamente invischiato in questo momento. Il prodotto ha bisogno di accesso e non sono sicuro di poterli sbrogliare. Penso di non poter aggirare il fatto che Product
abbia bisogno di Access
. Forse ho solo bisogno di tirare fuori le linee di codice attualmente scarsamente posizionate che controllano l'accesso, e metterle nella loro propria classe di Access e chiamare quella classe ProductAccess
, o qualcosa di simile. Potrebbe non esserci modo di aggirarlo, ma non sono del tutto sicuro di come farlo correttamente. DI sembra essere inappropriato (?)
Il mio obiettivo a breve termine è quello di voler testare il codice per ProductA
, senza prendere in giro la classe di accesso. Ma questo potrebbe essere un obiettivo sbagliato da avere. Forse ho bisogno di prendere in giro Access, dal momento che testerò il prodotto senza sapere quale livello di accesso ha bisogno ...
Il mio obiettivo generale è trovare il modo di disaccoppiare le classi il più possibile, mantenendo le funzionalità esistenti e eliminando il modello di registro che ho ora. C'è un modo per farlo, o il mio obiettivo è imperfetto?