领域驱动无分层

ddd的核心是领域模型,包括聚合根,领域服务,外围是应用服务,资源库。

应用服务和资源库是并列服务于领域的,资源库并不是最底层于数据库打交道的,而是与应用服务并列的。资源库强调的是对聚合根的集合的操作,是领域与数据库的隔离。隔离了领域与数据库的耦合。

领域驱动架构的架构是六边形架构,外围服务是可插拔的,服务于核心领域服务的。

领域驱动架构图:

《霸王别姬》首看,不错

这个电影早听说过,才看。是不是很out了。这部电影通过演唱霸王别姬的两位京剧演员,展示了近代京剧的历史,和京剧人的酸甜苦辣,充分展示了各个近代历史阶段,京剧人的人生经历,包括清末时期,民国时期,解放战争时期,建国初,文化大革命时期。让人看着,五味杂粮,感情很丰富,内容很深刻。

看过一遍,还会再看,因为内容太丰富了,总想了解细节。有个疑问,电影开头虞姬为什么比霸王要多说一年?

国荣的剧打算再追一追。老人的剧还是值得一看的。

时隔十几年又买回来dell latitude

进来新添笔记本计划,我思考了我的用本需求,高cpu,高内存,固态,用于软件开发。考虑来考虑去,还是dell商务本性价比最高。

最终买了dell latitude 5501, i7 9850h,32g内存,1t固态。原来考虑thinkpadp50,扩展性最好,但是考虑到32g内存的升级费用,还是算了吧。苹果本并不十分感冒,听说挺好,但是考虑到配置,特别是内存配置,还是不划算。最终才选择了这款,买就买吧,希望不要让我失望。

resttemplate.exchange远程调用

String url = "http://"+ dataPickerIpAndPort+"/myHouse/getMyHouse?userName="+userName+"&idCard="+idCard+"&buyer="+buyer+"&contractNum="+contractNum; 
try {
System.out.println("findCompanies's url:"+url);
body = restTemplate.exchange(
url
, HttpMethod.POST
, null
, new ParameterizedTypeReference<AnswerDTONew<MyHouseDTO>>() {
}).getBody();
if(body==null){
return new AnswerDTONew(true,"not found",new MyHouseDTO(), CommonState.ERROR);
}
}catch (Exception e){
return new AnswerDTONew(true,e.getMessage(),"", CommonState.ERROR);
}
@RequestMapping(value = "/myHouse/getMyHouse")
AnswerDTONew<MyHouseDTO> getMyHouse(@RequestParam(name = "idCard") String idCard,
@RequestParam(name = "buyer") String buyer,
@RequestParam(name = "contractNum") String contractNum);

使用重载避免过多修改客户代码

比如原先计算最大值有个方法,是根据字段id计算最大值

private Long getMaxId(String table){
List<Map<String, Object>> maps = jdbcTemplate.queryForList("select max(id) mid from " + table);
if(maps.size()>0){
Long mid = (Long) maps.get(0).get("MID");
return mid;
}else{
return 1L;
}
}

然后客户有很多调用了此代码。

后来有发现有需求要根据其他字段来计算最大值。

那么,是如果简单在上面方法上增加参数,就会导致调用方代码大量修改。

这时,可以保留上述方法,增加一个重载方法

private Long getMaxId(String table, String field){
List<Map<String, Object>> maps = jdbcTemplate.queryForList("select max("+field+") mid from " + table);
if(maps.size()>0){
Long mid = (Long) maps.get(0).get("MID");
return mid;
}else{
return 1L;
}
}

那么原来的方法,只需要调用次方法即可。

private Long getMaxId(String table){
return getMaxId(table,"id");
}

这样既避免了客户代码的大量修改,又避免了两个重载方法的代码重复冗余。

StringBuffer拼接sql的新写法

append,append,append重要的事情说三遍

例如:

StringBuffer insPersonRelation = new StringBuffer();
insPersonRelation.append("insert into houseproperty.personrelation")
.append("id,persontype,personid,register_id,register_type,personname)")
.append("values(")
.append(maxId).append(",'")
.append(persontype).append("','")
.append(personid)
.append(register_id).append("','")
.append(register_type).append("',")
.append("'").append(personName).append("'")
.append(")");

另一个java自定义异常

有时候为了简化业务判断,可以抛出自定义异常,然后在最顶层,根据异常信息返回不用的信息。

定义系统异常基类:

public class BusinessException extends Exception {
private static String baseMsg = "business exception:";
public BusinessException(String msg) {
super(baseMsg+msg);
}
}

子类1:

public class OpenIdIsEmptyException  extends BusinessException {
private static String msg = "openId is empty";
public OpenIdIsEmptyException() {
super(msg);
}
}

子类2:

public class UserIsNotExistException extends BusinessException {
private static String msg = "user is not exist";
public UserIsNotExistException() {
super(msg);
}
}

底层抛出

}else{
logger.info("userName:{} is not exist",userName);
throw new UserIsNotExistException();
}

方法抛出

throws OpenIdIsEmptyException, UserIsNotExistException 

顶层捕获

} catch (UserIsNotExistException e) {
e.printStackTrace();
logger.info("UserIsNotExistException"+e.getMessage());
return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
}