[Architecture Design] 累进式Domain Layer

时间:2022-05-02 16:14:48

[Architecture Design] 累进式Domain Layer

前言

本篇的内容大幅度的简化了分析设计、面向对象等等相关知识,用以传达累进式Domain Layer的核心概念。实际开发软件项目时,建议还是采用DDD、TDD等等系统化方式来分析设计系统内容。

问题情景

软件项目套用三层式体系结构,可以将程序代码分门别类提供系统化的整理归类。

[Architecture Design] 累进式Domain Layer

理论上,分析设计Domain Layer的时候,应该要从领域层的角度切入,去分析设计领域层的组成结构。但实作上,人类的思考惯性常常会带着开发人员使用Presentation Layer的角度,去分析设计Domain Layer的组成结构。例如:下列的商城系统,包含了购物车、商品查询这两个使用案例。

[Architecture Design] 累进式Domain Layer

购物车这个使用案例,提供一个页面让使用者可以查询购物车购物列表,点击列表项目可以看到商品内容。依照页面的需求,开发人员可能会建立一个ShoppingCartService类别来提供领域层的服务,这个类别包含了两个方法:查询购物清单(GetAllPurchase)、取得商品内容(GetProductDetail)。

[Architecture Design] 累进式Domain Layer

商品查询这个使用案例,提供一个页面让使用者可以商品编号来查询商品,并将查询到的商品内容显示在页面上。依照页面的需求,开发人员可能会建立一个ProductQueryService类别来提供领域层的服务,这个类别只包含了一个方法:取得商品内容(GetProductDetail)。

[Architecture Design] 累进式Domain Layer

经由实作上面两个使用案例,可以在领域层内建立ShoppingCartService、ProductQueryService两个类别。但是仔细检视两个类别的方法,会发现GetProductDetail这个方法重复了。这时有经验的开发人员,就会精炼领层将共享的方法抽取出来,建立为一个共享的ProductCommonService类别,用以避免不必要的程序代码重复。

[Architecture Design] 累进式Domain Layer

到目前为止,看起来软件架构一切正常,服务可以不停地依照系统需求被扩展,需要什么页面就在领域层扩展出对应的服务,并且从中不停精炼出共享服务。但是上述这个软件开发架构,其实仅适用于开发人数较少的开发团队;如果将开发情景拉高到多人共同开发的情景,会发现要从系统中精炼出共享服务,必须要有个人不停审核每个成员产出的服务,才能分析出共享的方法,接着在领域层中建立共享的服务。先不提一般开发团队是否拥有这样的人力配置,光是想想这个人员要审核所有的服务、并且发觉重复的程序代码,这个工作量就让人觉得头皮发麻,甚至可以说这是个不可能的任务。

[Architecture Design] 累进式Domain Layer

解决方案

为了解决上述问题情景所会造成的问题,在软件开发架构设计的时候,就需要先设计好Domain Layer,让领域层拥有「累进程序代码」的能力。

以同样的商城系统,包含了购物车、商品查询这两个使用案例来说,可以先由软件架构师,定义Domain Layer该拥有甚么样的基础类别(ShoppingCartService、ProductService),这些基础类别一开始的时候不包含任何方法,只定义了这些基础类别的职责范围。(EX:ShoppingCartService负责购物车相关逻辑、ProductService负责商品相关逻辑)

[Architecture Design] 累进式Domain Layer

实做购物车这个使用案例的开发人员,依照页面的需求会需要建立两个方法:查询购物清单(GetAllPurchase)、取得商品内容(GetProductDetail)。这时可以依照基础类别的职责范围,将GetAllPurchase散落到ShoppingCartService类别、将GetProductDetail散落到ProductService类别。再由购物车页面去使用这两个类别的方法,就可以完成使用案例的需求。

[Architecture Design] 累进式Domain Layer

实做商品查询这个使用案例的开发人员,依照页面的需求会需要建立一个方法:取得商品内容(GetProductDetail)。这时可以依照基础类别的职责范围,将GetProductDetail散落到ProductService类别,但是马上会发现GetProductDetail方法在先前实作购物车使用情景的时候,已经被实做完成。那开发人员就可以很轻松的直接使用ProductService类别上的GetProductDetail方法,来完成商品查询的使用案例需求。

[Architecture Design] 累进式Domain Layer

透过上述步骤,就能不停增加Domain Layer中各种基础类别的方法。而在基础类别的职责范围不足以覆盖项目范围的时候,也可以继续增加基础类别项目来覆盖更多职责范围。透过这样不断累进的方式,最终就能在Domain Layer中完整封装软件项目背后的领域知识。后续遇到新的使用案例,只要组合调用已经封装好的类别与方法,就能快速满足使用案例的开发需求。

[Architecture Design] 累进式Domain Layer

后记

以DDD的角度去看,Entity、Service、Repository等等领域对象的定义,都可以拿来做为Domain Layer累积程序代码的基础类别,系统所以要提供的各种方法都可以散落在这些领域对象之上。DDD的相关分析设计资料可以参考: