tip:不能偷懒的框架不是好框架
面向网络业务对象编程专栏
状态同步
业务实现
业务需求:用户登录成功后,为Money属性赋置100
面向业务编程:BO
前端业务代码
Patient patient = new Patient();
if(patient.login()){
System.out.println(patient.getUsername() + "登录成功");
}
else System.out.println(patient.getUsername() + "登录失败");
后端业务代码
public class User{
private String username;
private String password;
private int money;
//get、set方法....
public boolean login(){
if("839336369".equals(this.username) && "123456".equals(this.password)){
this.money = 100;
return true;
}
else return false;
}
}
神奇之处在于this.money=100
,这个服务方新的User状态,可以自动同步到请求方User。
也就是说:后端设置了该值,前端也会变更为该值,始终保持状态同步。
BO模式会非常简明,直接将BO作为网络元进行传输,省去了DTO的转化。
面向数据编程:Service+DTO
前端业务代码
//创建Entity
User user = new User();
user.setUsername("839336369");
user.setPassword("123456");
//配置Request
LoginRequest loginRequest = new LoginRequest();
loginRequest.setUsername(user.getUsername());
loginRequest.setPassword(user.getPassword());
//创建Service
UserService service = new UserService();
//获取Response
LoginResponse loginResponse = service.login(loginRequest);
if(loginResponse.isSuccess()){
user.setMoney(loginResponse.getMoney());
System.out.println(user.getUsername() + "登录成功");
}
else System.out.println(user.getUsername() + "登录失败");
如果是DTO模式,服务端会构造一个ResponseDTO反馈至请求方,请求方根据DTO数据,人工同步Patient中的Money属性。
后端业务代码
//Entity实体
public class User{
private String username;
private String password;
private int money;
//get、set方法....
}
//Service++DTO+BO模式(人工构造BO业务对象)
public class UserService{
public LoginResponse login(LoginRequest request){
User user = new User(request.getUsername(),request.getPassword());
if(user.login()){
return new LoginResponse(true,user.getMoney());
}
else return new LoginResponse(false);
}
}
//Service+DTO+Entity模式(人工构造Entity对象)
public class UserService{
public LoginResponse login(LoginRequest request){
User user = new User(request.getUsername(),request.getPassword());
if("839336369".equals(user.getUsername()) && "123456".equals(user.getPassword())){
return new LoginResponse(true,100);
}
else return new LoginResponse(false);
}
}
//Service+DTO模式(直接面向数据,不构造Entity,对本地业务BO产生摧毁)
public class UserService{
public LoginResponse login(LoginRequest request){
if("839336369".equals(request.getUsername()) && "123456".equals(request.getPassword())){
return new LoginResponse(true,100);
}
else return new LoginResponse(false);
}
}
为什么不推荐Service+DTO
1.类灾难
使用Service+DTO模式在对两个BO对象业务进行拆解时所产生的类对象。
面向业务对象网络编程
与原生业务逻辑持语义高度一致,自然业务架构也与原生业务逻辑一致,非常的简洁。
2.代码冗余
//配置Request
LoginRequest loginRequest = new LoginRequest();
loginRequest.setUsername(user.getUsername());
loginRequest.setPassword(user.getPassword());
//创建Service
UserService service = new UserService();
//获取Response
LoginResponse loginResponse = service.login(loginRequest);
if(loginResponse.isSuccess()){
user.setMoney(loginResponse.getMoney());
System.out.println(user.getUsername() + "登录成功");
}
else System.out.println(user.getUsername() + "登录失败");
很长很长的代码段,但你是不是觉得敲完这波就算结束啦?
当然没有那么简单t.t,任何用到该网络请求的位置,都需要构造DTO。
也就是说这段代码,你需要不断地Copy and Paste
- 前端跑来和你说:“这啥啊,到处复制都快吐了,我不干了-。-!”
- 后端跑来表示完全没有问题呀,你看这个数据多简明~
- 好的,1:1,你考虑到数据简明,前端麻烦点就麻烦点吧。
- 前端愤懑的跑回岗位,大力的敲打着
Ctrl+C
Ctrl+V
3.微服务
公司如火如荼的发展,很快就到了网络架构重构的日子,分布式、集群、微服务的概念逐渐闯入公司业务内部。
不出意外,某一天,后端悄悄跑来和你说“能不能别搞微服务了。。”
你开始纳闷了,为啥?(前端悄悄跑来凑热闹)
- 后端:“自从开始搞微服务,后端需要对不同微服务进行组合调用,我得不停的
Copy and Paste
,太累了呀t.t ” - 前端:“你个老六!当初我
Copy and Paste
你可是大力支持的!” - 好的,2:0,你开始思考
Copy and Paste
出现的问题了。
约束性
DTO固然简明,但是如果对DTO进行修改,所有Copy and Paste
DTO的代码段都需要更改。
如果回退到Entity,就不需要构造DTO了,但写请求文档不具有强约束性,又会出现数据协商不一致、数据过滤、数据安全等一系列问题。
语义性
UserService.login(new LoginRequest(user.getUsername(),user.getPassword()))
前端:“不管你们信不信,至少我觉得真变扭。”
后端:“为啥?”
前端:“用户登录: user.login()
vs UserService.login(LoginRequest)
你觉得哪个读的顺口?”
后端:“你是不是懒得构造DTO?行吧,允许你直接传Entity:UserService.login(user)
”
前端:“用户登录: user.login()
vs UserService.login(user)
你觉得哪个读的顺口?”
后端:“事真多,你请求的不就是我的服务嘛,叫服务有啥不可以的?”
前端:“好呀,你别忘了现在不光我在用,你自个儿也在用。”
后端:“。。。。我觉得确实有必要提高一下代码可读性。”
你开始思考,问题出在了哪里?
Service
控制多个BO
业务对象完成具体业务逻辑,十分合理。
等等!问题出现在Service现在控制的是多个Entity
!
也就是说,单体BO
的业务操作也转为了Service
+Entity/DTO
。
曾经是单体BO and Service+组合BO
现在为Service+单体Entity and Service+组合Entity
转就转吧,一个BO对象而已╮(╯_╰)╭
等等!现在可是微服务啊!这不是一个BO两个BO的事情!
你的所有服务都是基于单体BO组合而成,单体BO如果只能通过Service+DTO来实现,那简直是从根子上长满了Copy虫
。
你感叹:“果然最简逻辑还是原始单机逻辑啊!”
编程杰作
if(user.login()){
user.study(java).by(pc);
}
编程迷惑
if(UserService.login(new LoginRequest(user.getUsername(),user.getPassword())).isSuccess()){
user.setStudy(java);
StudyResponse response = UserService.study(new StudyRequest(user.getStudy(),pc));
user.setStudyResult(response.getResult());
}
结束语
如果状态同步不好理解,我们还可以理解为数据共享,BO实体的状态(属性)在请求方与服务方进行共享。
本章的状态同步只是实现理想框架的第一步,想要实现我们最终的目标,后面还有大量需要解决的问题并且需要提出一些类似状态同步
这类新的术语概念,such as 网络引用
。