È un'implementazione valida del pattern del repository?

6

Ho letto il pattern del repository, con l'intenzione di implementarlo nella mia applicazione. Quasi tutti gli esempi che ho trovato su Internet utilizzano una sorta di framework esistente piuttosto che mostrare come implementarlo "da zero". Ecco i miei primi pensieri su come potrei implementarlo - mi stavo chiedendo se qualcuno potrebbe darmi dei consigli se è corretto?

Ho due tabelle, denominate CONTAINERS e BITS. Ogni CONTENITORE può contenere un numero qualsiasi di BIT. Li rappresento come due classi:

class Container{
    private $bits;
    private $id;
    //...and a property for each column in the table...

    public function __construct(){
        $this->bits = array();
    } 

    public function addBit($bit){
        $this->bits[] = $bit;
    }

    //...getters and setters...
}

class Bit{
    //some properties, methods etc...
}

Ogni classe avrà una proprietà per ogni colonna nella rispettiva tabella. Poi ho un paio di 'repository' che gestiscono cose da fare con il salvataggio / recupero di questi oggetti dal database:

//repository to control saving/retrieving Containers from the database
class ContainerRepository{

    //inject the bit repository for use later
    public function __construct($bitRepo){
        $this->bitRepo = $bitRepo;
    }

    public function getById($id){
        //talk directly to Oracle here to all column data into the object 

        //get all the bits in the container
        $bits = $this->bitRepo->getByContainerId($id);
        foreach($bits as $bit){
            $container->addBit($bit);
        }

        //return an instance of Container
    }

    public function persist($container){
      //talk directly to Oracle here to save it to the database
        //if its ID is NULL, create a new container in database, otherwise update the existing one

        //use BitRepository to save each of the Bits inside the Container
        $bitRepo = $this->bitRepo;
        foreach($container->bits as $bit){
            $bitRepo->persist($bit);
        }
    }
}

//repository to control saving/retrieving Bits from the database
class BitRepository{
    public function getById($id){}
    public function getByContainerId($containerId){}
    public function persist($bit){}
}

Pertanto, il codice che utilizzerei per ottenere un'istanza di Container dal database sarebbe:

$bitRepo = new BitRepository();
$containerRepo = new ContainerRepository($bitRepo);
$container = $containerRepo->getById($id);

O per crearne uno nuovo e salvarlo nel database:

$bitRepo = new BitRepository();
$containerRepo = new ContainerRepository($bitRepo);

$container = new Container();
$container->setSomeProperty(1);
$bit = new Bit();
$container->addBit($bit);
$containerRepo->persist($container);

Qualcuno può consigliarmi se ho implementato correttamente questo modello? Grazie!

    
posta user1578653 19.08.2014 - 18:21
fonte

2 risposte

4

L'implementazione mi sembra corretta.

L'approccio potrebbe non adattarsi bene, perché:

  • Ricrea un oggetto ogni volta in getById ,

  • Passa in rassegna tutti gli oggetti in persist , mentre forse solo uno modificato,

Ma fare un'ottimizzazione prematura sarebbe peggio: se le prestazioni corrispondono alle tue aspettative in questo momento, non cambiare nulla.

Successivamente, se le prestazioni diventano un problema, prendi in considerazione:

  • Implementazione della strategia di memorizzazione nella cache (dato che probabilmente sarà esterno il repository, come strato aggiuntivo tra il repository e il codice che utilizza il repository),

  • Utilizzare il pattern observer per tenere traccia delle modifiche negli oggetti: in questo modo, quando persist ing cambia, non è necessario eseguire operazioni aggiuntive e aggiornare solo i dati effettivamente modificati.

risposta data 19.08.2014 - 18:47
fonte
3

Penso che tu stia facendo più di un Data Mapper , e come tale mi sembra corretto.

In un rigoroso punto di vista DDD (Domain driven design), il pattern di Repository è uno dei più schemi mal interpretati / abusati. In molti esempi che troverai online, il "repository" è implementato come un livello di astrazione del database, spesso implementato con un ORM. Tuttavia, in un contesto DDD, un Repository è una raccolta di Aggregati, non appartenenti al livello di accesso ai dati, ma nel livello di dominio / business logic dell'applicazione. An Aggregate incapsula un cluster di oggetti per proteggerne gli invarianti, esponendo solo la sua entità root (controlla questa domanda per maggiori dettagli: link ).

Vorrei "dimenticare" il pattern del repository e dare un'occhiata a CQRS (Command Query Responsibility Segregation). Se la tua applicazione contiene una complessa logica di business, potrebbe essere una buona idea implementarla con gli schemi tattici di DDD.

    
risposta data 20.08.2014 - 16:42
fonte

Leggi altre domande sui tag