代码之家  ›  专栏  ›  技术社区  ›  Peter

最佳实践:多个实体到单个实体

  •  0
  • Peter  · 技术社区  · 15 年前

    这是一个很难解释的问题,我希望我的代码摘录能解释大部分问题。

    假设您有以下数据库设计: musicstyle relations http://img190.yfrog.com/img190/2080/musicstylerelations.jpg

    您需要构建一个通用接口来修改这三个实体之间的音乐风格关系。目前我已经创建了一个MusicStyleController,它需要与之相关的实体类型(成员、事件或乐队)。

    [AcceptVerbs(HttpVerbs.Post)]
    public JsonResult DeleteMusicStyle(int id, string type, int typeid)
    {
        if (!(Session["MemberLoggedIn"] is Member)) return Json(string.Empty);
        Member member = (Member)Session["MemberLoggedIn"];
    
        switch (type) { 
            case "member":
                _memberService.DeleteMusicStyle(member, id);
                break;
            case "band":
                Band band = _bandService.GetBand(typeid);
                _bandService.DeleteMusicStyle(band, id);
                break;
            case "event":
                Event @event = _eventService.GetEvent(typeid);
                _bandService.DeleteMusicStyle(@event, id);
                break;
        }
        return SelectedMusicStyles();
    }
    

    我写这样的代码让自己恶心,但找不到另一种更优雅的方式。

    请注意,此函数是使用jquery.post()调用的。

    问题

    您将如何重构此代码,并将数据库规范化得更高?请记住,我将实体框架用作数据模型。

    2 回复  |  直到 15 年前
        1
  •  1
  •   Joseph    15 年前

    假设ID代表成员的ID,您可以创建3个单独的函数来处理每种类型,从而比现在更能分离您的关注点。

    例子:

    [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();
    }
    

    然后,您只需修改jquery文章,根据您要做的事情转到相应的方法。

        2
  •  1
  •   JARC    15 年前

    如何重构此代码?

    1)应移动检查用户登录的代码:

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

    这是一个跨领域的问题,应该使用安全框架来应用,Spring就是一个例子。

    2)我将避免使用单例模式来表示这个用例,它们可以快速地变成一组脚本,当它们变大时,很难知道将代码放在哪里。考虑改用命令模式。

    此模式将允许您根据命令要遵循的接口以JSON、XML或任何其他格式返回结果。

    class DeleteMusicStyleByBandCommand : JsonResultModelCommand, XmlResultModelCommand {
    
      public DeleteMusicStyleByBand(int id, int typeid) {
         //set private members
      }
    
      public void execute() {
        ..
      }
    
      public JsonResult getJsonResult() { .. }
    
      public XmlResult getXmlResult() { .. }
    }
    

    命令模式imho在表示用例方面比服务中的许多方法要好得多。