Mvc 和 Ddd 做了哪些分解?

·

1 min read

最初的软件系统,在架构上都非常朴实无华,用户在界面上点击按钮,然后执行对应的程序。对于使用关系型数据库为持久化方案的 Web 应用软件来说,这个流程相当于用户点击网页上的链接、按钮,服务器根据用户的请求生成并执行 SQL 并返回 SQL 的执行结果。这样的软件在进行扩展和维护时,非常困难,想要理解系统,你必须阅读从网页到业务逻辑的全部代码。

后来就有了分层架构,其中最广为人知的就是 MVC 架构,它把原本“一坨”的系统分成Model、View、Controller三部分,它的告诉我们应该把 Model 和 View 分开,用户在操作之后,由 Controller 来理解用户的操作意图,并执行Model层的业务(包括读写数据库),最后把结果显示在 View 上。随着计算机科学与软件工程的发展,越来越多的人开发软件来处理极其复杂的业务逻辑,尽管使用了 MVC 架构,但在 Model 层业务逻辑与技术逻辑混杂在一起,还是让人难以理解业务。体现在 Web 应用上,就是业务逻辑与数据库模型深度绑定,想要理解业务,你必须通读Model层的代码和数据库模型。

再后来,有人(Eric Evans)提出了 DDD,一种指导设计业务逻辑复杂软件系统的方式。DDD 告诉我们不光要把 Model 和 View 分开,在 Model 里还要把技术逻辑和业务逻辑分开,根据业务建立独立的领域模型。控制层在得到用户意图后,分别执行业务和技术逻辑。这个核心逻辑不但告诉我们应该针对软件建模而不是建立数据库模型,并且需要将技术与业务逻辑分离,在领域模型内实现所有业务属性、业务规则,而数据库只用来保存业务状态。

在软件开发领域内,还流行一种 Service 层(DDD 中被称为 Application 层),在 MVC 年代通常负责让 Controller 处理请求并使 Service 执行逻辑,这样的分层其实是有一点区分技术逻辑与业务逻辑的想法,但在持久层还是没有区分。而采用 DDD 后,业务逻辑和技术逻辑完全区分,这样如果你的技术逻辑比较简单,就没有必要单独分开,完全可以和 Controller (DDD 中被成为 Interface 层)写在一起(Eric Evans 这么认为)。在技术逻辑比较简单的情况下,你如果强行将 Interface 与 Application 分开,你的代码可能看起来像是这样的:

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public Response operation(OperationParameter param){
        return operationService(param);
    }

而这完全是没事找事。只有当你的请求参数需要转换才能变成模型,模型需要转换才能变成返回参数(序列化与反序列化),这些工作就应该交给 Interface 来做;或是你的操作包含多个需要明确编程的业务步骤、模型需要转换才能交给基础架构层,则这些工作应该交给 Application 来做。