2010-01-21 4 views
3

Nous avons deux types de domaine: Utilisateurs et Emplacements."Points de vue" dans le modèle d'objet

Nous avons une méthode sur l'LocationRepository: GetUserLocations().

La mise en œuvre existante:

var user = UserRepository.GetUser(userId); 
var locations = LocationRepository.GetUserLocations(userId); 

Pour moi, il est plus logique de récupérer les emplacements associés à un utilisateur du utilisateur Type-à-dire:

var user = UserRepository.GetUser(userId); 
var locations = user.GetLocations(); 

Je pense que cette dernière mise en œuvre se lit comme suit plus proprement et en tant que client API je dois traiter avec moins de types (ie le LocationRepository n'est pas requis). D'autre part, il y aura plus de code à maintenir car je dois écrire la "façade" au LocationRepository.

Dois-je agir sur mon instinct et créer une façade sur le utilisateur de type à la LocationRepository, ou devrais-je être heureux avec le statu quo et vivre avec un diagramme de séquence qui « se sent » tort de me (c.-à- la récupération de l'information de localisation a l'impression qu'elle est récupérée du mauvais "point de vue")?

+0

+1 Bonne question, je fais d'habitude un va-et-vient entre ces deux concepts. Très curieux ce que les gens ont à dire à ce sujet. –

+0

Pas encore de réponse? Bummer. Pouvons-nous bosse cette question? :) –

+0

@Ben Aston: quelle plateforme? .NET/C#? –

Répondre

1

Je l'aborderais du point de vue de la maintenabilité. Je suis d'accord que le faire avec la façade sur LocationRepository "se sentirait bien", et rendrait probablement le code légèrement plus lisible. Le compromis, comme vous l'avez dit, serait plus de code à maintenir. Mais de quel code parlons-nous? Est-ce beaucoup, et auriez-vous besoin de le mettre à jour souvent? Ou pouvez-vous l'écrire une fois et l'oublier, et l'avoir facilement testable? Si c'est le premier, il suffit de l'avaler, de suivre l'implémentation actuelle et de vous rappeler que cela n'affecte pas vraiment la fonctionnalité. Si c'est le dernier, il pourrait être utile de mettre l'effort pour ce bon sentiment et un code plus lisible ailleurs.

1

Il est sûrement possible de modéliser nos trucs quelque chose comme ceci:

Universe.Instance.Galaxies["Milky Way"].SolarSystems["Sol"] 
     .Planets["Earth"].Inhabitants.OfType<Human>().WorkingFor["Initech, USA"] 
     .OfType<User>().CreateNew("John Doe"); 

Peut-être que les instances dépôt ne devrait pas être visible pour le « développeur final » et être encapsulé dans le modèle. Toutefois, étant donné que nous n'avons pas forcément accès au Universe.Instance, nous avons besoin d'un ou de plusieurs «points d'entrée» pour savoir à partir de quelle source.

MISE À JOUR:

Je pense que d'une part, il devrait être un objectif de maintenir le nombre de là « points d'entrée de façade du référentiel » aussi bas que possible parce que se rapproche du monde réel, comme il est censé être seulement un "Bing Bang" d'où tout vient et qui a engendré toutes les données existantes finalement ;-) ... Cela dit, d'un autre côté, bien sûr, les systèmes d'aujourd'hui sont toujours de gros compromis que nous devons faire, parce que la capacité de modéliser le monde réel est limité, il y a des implications de performance et ainsi de suite ...

Une façon vous pouvez aller dans votre exemple concret est cependant d'utiliser vos dépôts pour toujours récupérer des nouvelles données, comme dans:

LocationRepository.Instance.GetUserLocations(userId); 

... alors que vous utilisez votre classe de modèle User pour tenir le résultat dans une propriété, comme dans:

var locations = myUser.Locations; 

Cette propriété utiliserait la technique de charge paresseux pour charger les données de la LocationRepository à première demande et tenir le résultat. Cela indique que les emplacements ne sont chargés qu'une seule fois, ce qui facilite les choses pour les développeurs qui utilisent votre bibliothèque. Vous pouvez ensuite décider si vous voulez rendre le LocationRepository.GetUserLocation (userId) également visible au développeur final ou non. Gardez à l'esprit que lorsque vous suivez cette route, vous devrez également créer une sorte de mécanisme d'actualisation implicite et explicite et de gestion de la durée de vie.

Cette approche globale s'est avérée très utile pour moi. Cependant, le monde asynchrone de Silverlight et al ajoute maintenant de nouvelles mises en garde, car de telles propriétés ne peuvent plus être actualisées instantanément et de manière synchrone avec une nouvelle valeur dans une ligne de code. Lorsque nous demandons une actualisation, nous devons maintenant tirer parti des techniques de liaison et/ou utiliser un rappel pour pouvoir ensuite traiter la valeur actualisée. Dans l'ensemble, le but ultime, je crois encore serait de voir par exemple un UserRepository comme un autre type de domaine ordinaire, apparemment avec la responsabilité de créer de nouvelles instances User et les ajouter au stockage des utilisateurs, ainsi pour fournir des vues filtrées (requêtes) sur tous les utilisateurs disponibles. Il serait acceptable que myUser.Locations ainsi que myLocations.ByUser["John Doe"] détiennent une référence au même résultat. Cette UserRepository pourrait alors simplement être une propriété d'une autre classe responsable de la tenir, comme CompanyStaff par exemple. Portant cette idée plus loin est ce qui m'a amené à cette chose Universe.Instance. ;-)

+0

Votre réponse est un peu ambiguë. Êtes-vous en faveur de la création d'une façade (ce qui en soi serait un «point d'entrée»), ou dites-vous que tout système est un gros compromis et que je peux donc utiliser directement le référentiel de localisation? – Ben

+0

Un peu des deux. ;-) ... J'ai mis à jour ma réponse avec une explication plus riche. – herzmeister

Questions connexes