2009-07-09 6 views
0

Il s'agit d'une question très difficile à expliquer et j'espère que mon extrait de code en explique la majeure partie.Meilleure pratique: plusieurs entités à entité unique

Disons que vous avez la conception de base de données suivante: musicstyle relations http://img190.yfrog.com/img190/2080/musicstylerelations.jpg

Et vous voulez construire une interface générique pour modifier les relations entre musicstyle les trois entités. Actuellement, j'ai créé un MusicStyleController qui nécessite le type d'entité auquel il est associé (membre, événement ou groupe). Je me rend malade en écrivant un tel code, mais je ne peux pas trouver un autre moyen, plus élégant.

Notez que cette fonction est appelée à l'aide de jquery.post().

La question

Comment décririez-vous factoriser ce code, et seriez-vous normaliser encore plus la base de données? Gardez à l'esprit que j'utilise Entity Framework comme modèle de données.

+0

Qu'est-ce que vous espérez gagner de normaliser la base de données? Quel volume de données attendez-vous (I.E., des dizaines de millions de lignes?) – Kane

+0

@Kane Je cherche une meilleure pratique dans ce cas, je ne sais pas encore ce que c'est. La base de données fournit une intégration fluide à Entity Framework et facilite le codage, si je la normalise encore davantage, par exemple créer une table MusicStyleCollection avec laquelle Band, Event et Member lieraient rendrait les choses plus difficiles à coder. Et ce serait un performancehit si la table devient exceptionnellement grande (ce qui sera probablement le cas). – Peter

+0

Je viens de l'ajouter comme suggestion car il pourrait y avoir un moyen de normaliser la base de données d'une manière à laquelle je n'ai pas encore pensé. Je ne me considère pas comme un développeur averti, je ne peux jamais l'être non plus ... – Peter

Répondre

1

En supposant que id représente l'identifiant du membre, vous pouvez créer 3 fonctions distinctes pour gérer chaque type, séparant ainsi vos préoccupations plus qu'elles ne le sont actuellement.

Exemple:

[AcceptVerbs(HttpVerbs.Post)] 
public JsonResult DeleteMusicStyleByMember(int id) 
{ 
    if (!(Session["MemberLoggedIn"] is Member)) return Json(string.Empty); 
    Member member = (Member)Session["MemberLoggedIn"]; 
    _memberService.DeleteMusicStyle(member, id); 
    return SelectedMusicStyles(); 
} 

[AcceptVerbs(HttpVerbs.Post)] 
public JsonResult DeleteMusicStyleByBand(int id, int typeid) 
{   
    Band band = _bandService.GetBand(typeid); 
    _bandService.DeleteMusicStyle(band, id); 
    return SelectedMusicStyles(); 
} 

[AcceptVerbs(HttpVerbs.Post)] 
public JsonResult DeleteMusicStyleByEvent 
    (int id, int typeid) 
{ 
    Event event = _eventService.GetEvent(typeid); 
    _bandService.DeleteMusicStyle(event, id); 
    return SelectedMusicStyles(); 
} 

Ensuite, vous simplement modifier votre message jquery pour aller aux méthodes respectives en fonction de ce que vous essayez de faire.

+0

J'ai pensé à ça mais il faudrait encore dupliquer le code que j'essaie d'éviter. Cela semble être une solution attrayante et s'il n'y a pas d'autre moyen logique, je le fais de façon déminente. – Peter

+0

@Peter Je ne sais pas comment cela duplique le code, sauf peut-être avoir plusieurs déclarations de méthode. En dehors de cela, chaque méthode a son propre comportement, même dans cet exemple. Si vous trouvez que les méthodes partagent certains comportements après le fait, vous pouvez refactoriser à nouveau ce point et consolider ce comportement particulier. – Joseph

+0

@Joseph Je dois dire que je suis d'accord avec vous. C'est probablement la meilleure solution. Je vais juste devoir tenir mes js responsables de savoir quelle action appeler. – Peter

1

Comment refactoriez-vous ce code?

1) Le code qui vérifie que l'utilisateur est connecté doit être déplacé:

if (!(Session["MemberLoggedIn"] is Member)) return Json(string.Empty); 
    Member member = (Member)Session["MemberLoggedIn"]; 

C'est une préoccupation transversale, qui devrait être appliquée au moyen d'un cadre de sécurité, printemps vient à l'esprit comme Exemple. 2) J'éviterais d'utiliser un motif singleton pour représenter ces cas d'utilisation, ils pourraient rapidement se transformer en une collection de scripts qui, une fois grands, peuvent être difficiles à savoir où placer le code. Envisagez d'utiliser le modèle de commande à la place.

Ce modèle vous permettra de renvoyer les résultats au format JSON, XML ou tout autre format basé sur les interfaces que votre commande doit également respecter.

class DeleteMusicStyleByBandCommand : JsonResultModelCommand, XmlResultModelCommand { 

    public DeleteMusicStyleByBand(int id, int typeid) { 
    //set private members 
    } 

    public void execute() { 
    .. 
    } 

    public JsonResult getJsonResult() { .. } 

    public XmlResult getXmlResult() { .. } 
} 

Le modèle de commande à mon humble avis est beaucoup mieux à représenter des cas d'utilisation que de nombreuses méthodes dans un service ..

+0

bonne idée! Cela permettra une bonne séparation du code. Je vais mettre en œuvre cela et voir où je me retrouve. – Peter

+0

Lors de la mise en œuvre de ce que j'ai réalisé que je dois encore créer des méthodes d'action dans mon contrôleur pour appeler ces commandes résultant en plus de code. En fin de compte, cela n'améliorerait pas la lisibilité ni la maintenabilité. Ces fonctions (par exemple deletebandmusicstyle) sont appelées à partir d'ajax. – Peter

+0

Vous êtes un 100% correct sur l'utilisation d'un cadre de sécurité, mais je n'ai pas eu le temps de passer par les avantages et les inconvénients des différents frameworks en combinaison avec asp.net mvc – Peter

Questions connexes