2010-11-19 3 views
2

J'essaie de comprendre comment réutiliser des modèles de domaine dans différentes parties de l'application et j'ai l'impression que le modèle Data Mapper est la solution. L'exemple ci-dessous contient des méthodes qui accèdent directement aux méthodes du mappeur.Objet de domaine nécessitant plusieurs mappeurs de données

class Groups 
{ 
    protected $_groups = array(); 

    public function addGroup($name) 
    { 
     $this->_groups[] = $name; 
    } 

    public function doSomethingGroupy($cakes) 
    { 
     // get all the groups that have cake 
     return $cakeyGroups; 
    } 
} 

... et un mappeur pour faire correspondre les méthodes de la classe Groups.

class GroupMapper 
{ 
    public function find($id, Groups $group) 
    { 
     // Mappy type things, maybe some sql 
    } 

    public function fetchByNeediness($cuddles, Groups $group) 
    { 
     // More mappy type things 
    } 

    public function save(Groups $groups) 
    { 
     // Saves 
    } 
} 

Cependant, si quelque temps que je voulais plus tard utiliser les mêmes modèles Groupes mais remplir les groupes en utilisant différentes requêtes que j'utiliseraient un autre cartographe.

class AngryGroupMapper 
{ 
    public function find($id, Groups $group) 
    { 
     // Something similar but with other tables and joins 
    } 

    public function fetchByRage($anger, Groups $group) 
    { 
     // Something new but only needed here 
    } 

    public function isEditable(Groups $groups) 
    { 
     // Do some querying 
     return $bool; 
    { 
} 

Maintenant, je sais que l'objectif est contrôleur Skinny - Modèle Fat, donc aurais-je un autre modèle à la carte du Mapper (pour ainsi dire) au modèle?

class FatModelRepository 
{ 
    public function getHappyGroups() 
    { 
     $mapper = new GroupMapper(); 
     return $mapper->fetchByNeediness('Puffy Shoes', new Groups()); 
    } 

    public function getSadGroups() 
    { 
     $mapper = new AngryGroupMapper(); 
     return $mapper->fetchByRage('Aghh!', new Groups()); 
    { 

    public function save(Groups $groups) 
    { 
     $mapper = new GroupMapper(); 
     return $mapper->save($groups); 
    { 
} 

Répondre

4

Le modèle de données ne doit pas avoir connaissance du Data Mapper. Votre classe/modèle de groupe ne devrait pas avoir de méthodes de recherche et il ne devrait pas avoir accès au mappeur. Une fois que vous avez supprimé la dépendance du mappeur de votre modèle, vos problèmes disparaîtront.

REMARQUE: consultez Doctrine 2

+0

Que faire si "Groups" est une collection contenant des objets "Group" et que ce sont des modèles eux-mêmes qui nécessitent un mappage dépendant. Devriez-vous les détacher des groupes, les passer à travers un mappeur, puis les rattacher à la collection? Cela signifie-t-il que le client/contrôleur a besoin des connaissances des mappeurs? – gawpertron

+0

Votre 'FatModel' s'appelle un référentiel. Il y a une bonne explication de ceci ici: http://msdn.microsoft.com/en-us/magazine/dd569757.aspx#id0400058 – rojoca

+0

Pourquoi voudriez-vous? Concevez-le en fonction de vos besoins. Je n'utiliserais pas de repo comme cache. Mettez le cache sur le mappeur de données. – rojoca

0

Comme rojoca dit que vous ne devriez pas avoir les méthodes Fetch/trouver directement sur le modèle. Techniquement, il est également vrai que le modèle ne stocke pas de référence au mappeur, mais dans des situations moins complexes, je pense que c'est correct tant que le modèle ne dépasse que la forme la plus abstraite de mapper que vous prévoyez avoir. classe ou une interface). Compte tenu de cela, vous ne devriez avoir besoin d'ajouter des méthodes au mappeur, et pour cela, je voudrais juste utiliser l'héritage, c'est-à-dire. étendre votre mappeur de groupes pour la nouvelle fonctionnalité. Bien sûr, cela nécessite que le mappeur soit injectable dans le modèle. Mais si vous voulez que le modèle tienne une référence à son mappeur, alors il doit être injectable de toute façon.

+0

Lors de mes premières tentatives, j'ai ajouté une référence au mappeur et je me suis rendu compte très tôt des limites de cette opération. Cependant, je n'arrive pas à imaginer comment utiliser les mappeurs sans un modèle ou un contrôleur quelque part en étant conscient? – gawpertron

+0

i dodnt pense qu'il y a quelque chose de mal avec vos contrôleurs utilisant directement les mappeurs car les contrôleurs sont spécifiques aux applications/modules. – prodigitalson

+0

Un mappeur peut-il connaître un autre mappeur? – gawpertron

Questions connexes