2011-11-29 36 views
2

你正在使用你自己的版本的计算器:-)什么地方适合商业逻辑?

你正在使用ASP.NET MVC和实体框架(模型优先的方法,如果它很重要)。所以,你有一对夫妇由EF生成的类:

class Question {...} 
class Answer {...} 

还拥有所有相关的东西(ObjectContext等)。你把所有的相关的代码来处理回答这个问题的方案(StackoverflowControllerAnswerQuestion [获得] + AnswerQuestion [文章]动作,也为了显示一个奇特的形式 - Stackoverflow/Answer)。

你的客户是一个非常艰难的家伙,所以他定义了一套商业规则:

  1. 没有人应该能够回答这个问题在第5分钟的问法后(他们应该得到的消息)。
  2. 答案发布后,主题发起人应收到通知。
  3. 主页面应该显示20个最新的问题。
  4. 当显示的每一个问题的答案,就应该通过投票排序。
  5. 当问题与总的-10 downvoted,它们应该被关闭。
  6. 当答案,总的-10 downvoted,他们的海报应该得到的-20抗奖金他们的声誉。

的问题是 - 鉴于上述事实,你会在哪里实现客户的业务规则?

我真的不喜欢具有类似于代码的想法:

public class HomeController : Controller 
{ 
    ... 
    public ActionResult Index() 
    { 
     return View(_container.Questions.OrderByDescending(x => x.Posted).Take(20).ToList()); 
    } 
} 

但你会如何命名这个逻辑正确的地方?它应该有什么接口?是这样的:

// implements the business logic, interacts with repositories 
public static class Stackoverflow 
{ 
    public static IEnumerable<Question> GetRecentQuestions() { ... } // logic here! 
    public static void PostAnswer(Question question, Answer answer) { ... } // logic here! 
} 

+0

这种话语,开放式问题真正属于http://programmers.stackexchange.com – APC

+0

标记为移动到程序员.stackexchange.com – agibalov

+1

典型的游戏开发者响应:“您应该使用StackoverflowManager类,它应该是静态的。此外,确保静态实例始终具有一种极其复杂的状态。” ^。^ –

回答

3

一种解决方案是使用一个服务层来处理这给你:

public Interface IStackoverflowService 
{ 
    IEnumerable<Question> GetRecentQuestions(); 
    void PostAnswer(Question question, Answer answer); 
} 

public class StackoverflowService : IStackoverflowService 
{ 
    private StackoverflowDbContext _container; 

    public StackoverflowService(StackoverflowDbContext container) 
    { 
     _container = container; 
    } 

    public IEnumerable<Question> GetRecentQuestions() 
    { 
     var model = _container.Questions.OrderByDescending(x => x.Posted); 
     return model.Take(20); 
    } 

    public void PostAnswer(Question question, Answer answer) { ... } 
} 

然后在你的控制器:

public class HomeController : Controller 
{ 
    private IStackoverflowService _stackoverflowService; 

    public HomeController(IStackoverflowService stackoverflowService) 
    { 
     _stackoverflowService = stackoverflowService; 
    } 

    public ActionResult Index() 
    { 
     var model = _stackoverflowService.GetRecentQuestions(); 
     return View(model); 
    } 
} 

你甚至可以打破它出成多个服务,如QuestionsServiceAnswersServiceUsersService

+0

很好的回答,建议把对StackOverflowService的接口,因此它可以被嘲笑的单元测试。 – jeremyalan

+0

@jeremyalan添加界面的一个例子。 – shuniar

+0

这个服务应该提供一个访问存储库的例子,例如“通过ID获取问题”吗?还是应该将'GetQuestionById()'作为'IStackoverflowService'的成员? – agibalov