从数据网络编程到业务网络编程:状态同步式网络编程

tip:不能偷懒的框架不是好框架


面向网络业务对象编程专栏

编程语义、业务架构量化分析(一)

状态同步式网络编程(二)


文章目录

  • 状态同步
    • 业务实现
      • 面向业务编程:BO
      • 面向数据编程:Service+DTO
  • 为什么不推荐Service+DTO
    • 1.类灾难
    • 2.代码冗余
    • 3.微服务
      • 约束性
      • 语义性
        • 编程杰作
        • 编程迷惑
  • 结束语


状态同步

业务实现

业务需求:用户登录成功后,为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的转化。
从数据网络编程到业务网络编程:状态同步式网络编程_第1张图片

面向数据编程: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);
	}
}

从数据网络编程到业务网络编程:状态同步式网络编程_第2张图片

为什么不推荐Service+DTO

1.类灾难

使用Service+DTO模式在对两个BO对象业务进行拆解时所产生的类对象。

从数据网络编程到业务网络编程:状态同步式网络编程_第3张图片
面向业务对象网络编程与原生业务逻辑持语义高度一致,自然业务架构也与原生业务逻辑一致,非常的简洁

从数据网络编程到业务网络编程:状态同步式网络编程_第4张图片

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. 前端跑来和你说:“这啥啊,到处复制都快吐了,我不干了-。-!”
  2. 后端跑来表示完全没有问题呀,你看这个数据多简明~
  3. 好的,1:1,你考虑到数据简明,前端麻烦点就麻烦点吧。
  4. 前端愤懑的跑回岗位,大力的敲打着Ctrl+C Ctrl+V

3.微服务

公司如火如荼的发展,很快就到了网络架构重构的日子,分布式、集群、微服务的概念逐渐闯入公司业务内部。
不出意外,某一天,后端悄悄跑来和你说“能不能别搞微服务了。。”
你开始纳闷了,为啥?(前端悄悄跑来凑热闹)

  1. 后端:“自从开始搞微服务,后端需要对不同微服务进行组合调用,我得不停的Copy and Paste,太累了呀t.t ”
  2. 前端:“你个老六!当初我Copy and Paste 你可是大力支持的!”
  3. 好的,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 网络引用

你可能感兴趣的:(QinsNet,rpc,架构,程序人生)