短知识:丰富你的领域(实体)对象

该文章主要介绍自己根据对领域驱动设计的理解结合开发实际而赋予领域对象更多的实际行为,而不仅仅是作为一个简单的数据载体而存在。

DO(Domain Object)优化

在贫血模型里,领域对象一般只作为数据载体而存在,只有get和set方法,这也导致一些简单的业务逻辑重复出现在多个地方,如仅把对象里的值提出来去处理判断,但这些行为放到对象中可以更加丰富DO的行为,增加代码可读性,下面以一个优化对象作为数据载体与赋予简单逻辑后的操作对比为例。

  • 作为数据载体的领域对象
@Data
@Accessors(chain = true)
public class Discount {
private Long id;
/**
* 状态(0-禁用,1-可用,2-过期) {@link DiscountConstant.Status}
*/
private Integer status;
/**
* 类型(1-折扣,2-优惠券) {@link DiscountConstant.Type}
*/
private Integer type;
/**
* 折扣/优惠券价
*/
private Integer value;
}

当需要进行一些逻辑处理,如返回优惠信息,判断状态等,可能就会在多处出现以下的代码块:

短知识:丰富你的领域(实体)对象

  • 赋予逻辑的领域对象
短知识:丰富你的领域(实体)对象

当要获取优惠信息时,如果返回页面的是Discount这个对象时,则无需任何处理了,getDiscountMsg方法会返回discountMsg信息;当作为逻辑处理获取信息时,也可以调用discountMsg而无需重复写类型判断与字符串拼接。进行状态判断时,使用领域对象里的方法进行判断更具有可读性:

if(discount.isStatusEquals(status)){
// do something
}

当然常量值较少时也可以使用isEnabled()判断对象状态是否为可用,但当常量值过多时会使对象过于臃肿。

VO(Value Object)优化

值对象在Web应用层中一般表示为表现层(前端)的对象,与DDD中的值对象有所不同。前端进行VO传参时,VO也可进行类似DO的优化,如复杂参数的校验,对象的转换,对象转换例子:

短知识:丰富你的领域(实体)对象

引申领域模型

  • 贫血模型:领域对象(DO)里没有业务逻辑,只含简单而的数据操作方法(如get、set、toString),从业务层面上看仅仅是一个数据载体在业务与存储介质之间进行传输的数据载体
  • 充血模型:领域对象里拥有自己的状态与行为,大多业务逻辑和持久化放在DO里,业务逻辑层只是简单封装部分业务逻辑以及控制事务等

贫血模型与充血模型应用分层差别不大,主要区别在于逻辑的处理,如下图(左图参考自《领域驱动设计:软件核心复杂性应对之道》,右图参考自《阿里巴巴Java开发手册》):

短知识:丰富你的领域(实体)对象

结合实际

充血模型对开发人员的业务了解要求较高,需要开发人员清楚的认知业务划分,什么需要放到service层,什么需要放到DO层,且DO中还包含DAO进行数据持久化(依赖倒置原则),这对开发人员来说十分混乱。但在实际开发中,并不一定必须按照死规则去编写代码,可以借鉴充血模型的逻辑处理,灵活开发,为贫血模型中的领域对象赋予数据对象一定的逻辑,提高代码的复用性、可读性。


分享到:


相關文章: