前言
一个理论:DDD可以创建获取模型数据
一个问题:通过rpc接口获取数据往往不是我们需要的还需要加工处理
一个设想:直接通过一个重用领域去拿到我们需要的东西
需求
1.获取用户权益过期时间,获取用户对于权益状态(从未购买,过期,生效)
2.已知rpc提供权益状态和权益时间
设计
1基础设施层
UserRightsRepository 此方法实现获取第三方rpc 返回对象
/**
* <h3> 基础设施层 用户权益Dao</h3>
*/
@Slf4j
@Service
public class UserRightsRepository {
@Autowired
private UserRightApi userRightApi;
public List<UserRightDTO> getBuyerUserRightsList(Long customerId, List<Integer> rightsCodeList) {
QueryCondition queryCondition = new QueryCondition();
List<UserRightDTO> userRightDTOList;
try {
userRightDTOList = userRightApi.findList(queryCondition);
} catch (Exception e) {
log.error("userRightApi findList error customerId {} rightsCodeList {}",customerId ,rightsCodeList,e);
throw new RuntimeException(e);
}
return userRightDTOList;
}
public RightsDTO getUserRights(Long customerId, String rightsCode) {
RightsQueryDTO rightsQueryDTO = new RightsQueryDTO();
Map<String, RightsDTO> stringRightsDTOMap;
try {
stringRightsDTOMap = userRightApi.userRightsDetail(rightsQueryDTO);
} catch (Exception e) {
log.error("userRightApi userRightsDetail error customerId {} rightsCode {}", customerId, rightsCode, e);
throw new RuntimeException(e);
}
if (MapUtils.isEmpty(stringRightsDTOMap)) {
log.error("userRightApi userRightsDetail 获取权益 error customerId {} rightsCode {}", customerId, rightsCode);
return null;
}
RightsDTO rightsDTO = stringRightsDTOMap.get(rightsCode);
if (Objects.isNull(rightsDTO)) {
log.error("userRightApi userRightsDetail 获取权益 error customerId {} rightsCode {}", customerId, rightsCode);
return null;
}
return rightsDTO;
}
}
2领域对象 充血模型
/**
* <h3>用户权益状态枚举值</h3>
*/
public enum UserRightsStautsEnum {
outDate("outDate","过期"),
noBuy("noBuy","从来没购买过"),
inDate("inDate","生效");
// 描述信息(备注)
private String type;
// 获取信息value 第三方对应字段
private String desc;
UserRightsStautsEnum(String type, String desc) {
this.type = type;
this.desc = desc;
}
}
@Slf4j
@Data
public class UserRightsRemainDayDomain {
private Integer remainDay;
private UserRightsStautsEnum userRightsStautsEnum;
public void setUserRightsStautsEnum(RightsDTO rightsDTO) {
this.userRightsStautsEnum = UserRightsStautsEnum.inDate;
//根据字段填充类型
}
public void setRemainDay(RightsDTO rightsDTO) {
this.remainDay = Math.toIntExact((endTime - currentSecond) / 86400 + 1);
//根据字段填充
}
public void fillByUserRightDTOList(List<UserRightDTO> userRightDTOList) {
this.userRightsStautsEnum = UserRightsStautsEnum.inDate;
this.remainDay = Math.toIntExact((endTime - currentSecond) / 86400 + 1);
}
}
3仓库
/**
* <h3>用户权益剩余时间 仓库</h3>
*/
@Service
public class UserRightsRemainDayRepository {
@Autowired
private UserRightsRepository userRightsRepository;
public UserRightsRemainDayDomain getUserRightsRemainDay(Long customerId, String rightsCode){
UserRightsRemainDayDomain userRightsRemainDayDomain = new UserRightsRemainDayDomain();
RightsDTO rightsDTO;
try {
rightsDTO = userRightsRepository.getUserRights(customerId, rightsCode);
} catch (Exception e) {
return null;
}
if(Objects.isNull(rightsDTO)){
return null;
}
userRightsRemainDayDomain.setUserRightsStautsEnum(rightsDTO);
userRightsRemainDayDomain.setRemainDay(rightsDTO);
return userRightsRemainDayDomain;
}
//获取一批权益的状态和生效时间 只要有一个权益的最后结束时间>现在 就在有效期
public UserRightsRemainDayDomain getUserRightsListRemainDay(Long customerId, List<Integer> rightsIdList){
List<UserRightDTO> userRightDTOList;
try {
userRightDTOList = userRightsRepository.getBuyerUserRightsList(customerId, rightsIdList);
} catch (Exception e) {
return null;
}
UserRightsRemainDayDomain userRightsRemainDayDomain = new UserRightsRemainDayDomain();
userRightsRemainDayDomain.fillByUserRightDTOList(userRightDTOList);
return userRightsRemainDayDomain;
}
}
4使用
@Override
public Integer getRightsOrderRemainDay(Long customerId) {
UserRightsRemainDayDomain userRightsListRemainDay = userRightsRemainDayRepository.getUserRightsRemainDay(customerId, UserRightsRpc.RightsCode.CHAT_MEMBER_PURCHASEORDER);
if(Objects.isNull(userRightsListRemainDay) || NumberExtendUtil.isNull(userRightsListRemainDay.getRemainDay())){
return -99999;
}
return userRightsListRemainDay.getRemainDay();
}
4 对比DDD 和 业务编程
1.DDD隔离了第三方api可以对第三方api的报错限流降级处理
2.DDD对于每一个属性赋值更加清晰 业务编程也可以使用填充对象的方式清晰对象赋值
3.DDD可能会导致有部分代码冗余执行,且有部分逻辑代码因为写在充血模型里面,无法重用
总结:DDD 对于之前 再写个类进行业务编程来说,更加的降维打击,用在变化的业务上也能更加顺畅,可以依据这个思想简化ifelse,依据DDD思想开发后流程图已经无法适用代码逻辑
展望
定时任务工具类中是否可用DDD来简化业务定时任务的流程