Pattern matrice del repository?

2

Sto provando molto seriamente a ridefinire parte del mio codice legacy nel progetto utilizzando best practice e pattern di progettazione + DDD, quindi mi piacerebbe avere un feedback su un problema che sto attualmente avendo.

Supponiamo di avere due classi di entità:

class Dog
{
    protected $name;

    function __construct($name)
    {
        $this->name = $name;
    }

    /**
     * @return mixed
     */
    public function getName()
    {
        return $this->name;
    }

    function bark()
    {
        echo 'Rawr';
    }
}

class Husky extends Dog
{
    /**
     * @var Sledge
     */
    protected $sledge;

    function __construct($name, Sledge $slegde)
    {
        parent::__construct($name);
        $this->sledge = $slegde;
    }

    function pull()
    {
        echo $this->sledge->pull();
    }
}

Dog è la mia entità regolare e la sua unica responsabilità è quella di mappare i campi del database. Husky d'altra parte ha le stesse responsabilità del cane ma delega anche Sledge pulling.

Normalmente, entrambe le entità avrebbero repository diversi (dovrebbero? Dal momento che uno eredita l'uno dall'altro) da richiedere, tuttavia i requisiti aziendali implicano che il cliente non deve specificare il tipo di cane (quindi può essere una percentuale "base"Dog o speciale Husky ), solo il suo nome http://localhost/animal/fluffy .

Inoltre, attualmente risiedono entrambi nella stessa tabella di database (riconosciuta dal campo type ) e al momento non ci sono piani tecnici per cambiarlo (per ragioni di prestazioni e di tempo).

Qual è il modo migliore per farlo?

  • Dovrei creare un po 'di AnimalRepository , estrarre i dati e trattarli come DTO, rilevare il suo tipo e quindi creare la classe appropriata?
  • Dovrei creare un qualche tipo di mappatore del livello di astrazione più alto? Come dovrebbe essere?
posta acid 17.06.2014 - 20:41
fonte

3 risposte

1

Possiamo risolvere qualsiasi problema introducendo un ulteriore livello di riferimento indiretto. Dubito che aggiungere un altro livello di astrazione risolverebbe il tuo problema.

Penso che la domanda che dovresti porre sia "Ho bisogno di due repository per questo o solo uno" e la risposta a questo dipende da molto più di quello che si può trovare qui ... Nessun danno nell'iniziare con quello Deposito di cani e trasferimento in repository separati quando diventa chiaro che il repository Dog deve avere metodi validi solo per gli husky e la struttura del tuo programma trarrebbe beneficio dalla separazione.

    
risposta data 11.03.2015 - 20:19
fonte
0

Non sono un esperto in materia, ma proverò una risposta. Secondo questo articolo il modello Repository è progettato specificamente per risolvere il tuo problema. Quindi nella mia comprensione dovresti avere un repository che restituirà l'animale concreto o astratto richiesto.

    
risposta data 20.06.2014 - 09:02
fonte
0

Penso che la risposta all'estensione del comportamento non possa essere astratta: dipende da un problema concreto. Se assumiamo che tirare slitta sia un comportamento insolito per i cani * (incapsulare ciò che varia) un altro livello di astrazione sarebbe la risposta, ma sarebbe diverso in caso di slitta trainante -contest-app dove un cane può tirare la slitta in generale, ma alcuni sono deboli da tirare o non hanno la slitta equipaggiata. Potresti anche avere un concorso generale per cani in cui il modello di strategia si applica con un metodo startCompetition() .

*) In questo contesto Husky class non è solo un cane, ma una composizione di un cane e una slitta. Vorrei iniziare con Husky di firma di classe che sarebbe simile a

class Husky extends Dog implements SledgePullingInterface {}
//or with another level of inheritance
class Husky extends SledgeDog {}

Ora è più semplice "sniffare il codice". Sembra strano quando Husky non è un sottotipo diretto di un cane - forse il nome dovrebbe essere diverso? Forse la classe SledgeDog è sufficiente o le classi specifiche della razza sono separate per un altro motivo? - non posso dirlo.

Se mappi h usky solo come cane (usando DogMapper) non può essere utilizzato in Husky contesto di classe. Solo un cane che sembra essere roco che si può capire ottenendo solo un campo "razza" - il quadrato è un rettangolo, ma non astratto. Per un oggetto di classe Husky completo di cui hai bisogno

new PullingSledgeDogMapper(DogMapper $dog, SledgeMapper $sledge);
    
risposta data 11.04.2015 - 03:40
fonte