充血模型的特点包括:
-
富含业务逻辑:在充血模型中,领域对象(如Java中的类)不仅仅是数据的容器,它们还包含了丰富的业务逻辑。这意味着业务规则、验证逻辑、计算等直接嵌入到领域对象内部。例如,一个
Order
类不仅有订单信息的属性,还包括处理订单状态变更、计算总价等行为方法。 -
领域为中心:设计时以领域专家的语言和概念为指导,力求模型能够准确反映业务领域,提高代码的可读性和业务表达能力。
-
提高内聚性,降低耦合:通过将相关的数据和操作封装在一起,充血模型有助于提高模块间的内聚性,减少不同模块之间的依赖,使得系统更易于维护和扩展。
-
促进领域知识的集中和复用:将业务逻辑集中于领域对象中,便于团队成员理解和维护业务规则,同时也便于在系统其他部分重用这些逻辑。
-
挑战与权衡:虽然充血模型提高了业务逻辑的清晰度和领域模型的表达力,但它也可能导致模型复杂度增加,特别是在大型项目中管理这样的模型可能会比较困难。此外,对于简单的 CRUD 应用,充血模型可能显得过度设计。
@Setter
@Getter
public class BasicMemberAppLoginPO {
@ApiModelProperty(value = "用户访问微信场景Code", example = "1005")
private String sceneCode;
private OutsideChannelPO query;
public String getValueByCode(String sceneCode) {
return McMemberWxSceneEnum.getSceneValue(sceneCode);
}
@Data
public static class OutsideChannelPO{
@ApiModelProperty(value = "用户访问外部渠道类型 LIVECODE:活码 WX_CP_WELCOME_MSG:企微欢迎语", example = "LIVECODE")
private MemberOutsideChannelTypeEnum outsideType;
@ApiModelProperty(value = "用户访问外部渠道id", example = "301")
private String outsideId;
@ApiModelProperty(value = "uuid", example = "oiugU68NF1d6kWNTPlbi0FURLiO0")
private String uuid;
public boolean isOutsideChannel() {
return ObjectUtil.nonNullOrEmpty(outsideType) && ObjectUtil.nonNullOrEmpty(outsideId);
}
}
}
BasicMemberAppLoginPO.OutsideChannelPO query = t.getQuery();
if (query == null) {
String sceneCode = t.getSceneCode();
member.setWeixinSceneCode(sceneCode);
member.setWeixinSceneValue(t.getValueByCode(sceneCode));
return;
}
//活码或企微欢迎语的小程序路径中可以携带小程序码的uuid 或 扫会员中心小程序码进入也会携带uuid信息,可以认为是扫码小程序码访问,在这里不记录 访问来源信息
if (query.getUuid() != null) {
return;
}
if (query.isOutsideChannel()) { ... }
如上代码,query作为前端调用接口,传递的request body,不管这个query有没有数据,在判断query == null的时候始终为false。
原因:在query对象里定义了一个isOutsideChannel的判断方法,那么 就会在query对象里显示 {"outsideChannel":false},所以不能直接以query这个对象是否为空来做逻辑判断;
public boolean notOutsideChannel() {
return ObjectUtil.allNull(getOutsideType(), getOutsideId(), getUuid());
}
这样却没有问题。。。
代码不规范,发布两行泪啊。。。
就是觉得isXxx,语义化,好理解,反而坑了自己。。。