- 有两个类 结构差不多,都在Order类里面用到,而且方法里面逻辑也差不多,怎么优化
- 因为Customer和Client不同类型,所以写了两个方法,只是传的参数不一样
- 自定义泛型可以实现么,怎么写比较好,或者其它有什么方式
- 谢谢
public class Customer {
private String location;
private Boolean isDone;
// get set toString ...
}
public class Client {
private String location;
private Boolean isDone;
// get set toString ...
}
public class Order{
public void execute_customer(Customer customer){
if(customer.getDone()){
customer.setLocation("hongkong");
}
System.out.println("result: "+ customer);
}
public void execute_client(Client client){
if(client.getDone()){
client.setLocation("hongkong");
}
System.out.println("result: " + client);
}
}
============================= 情况二 =====================================
public List<Customer> retrieveEntityRecords(RequestParam request) {
List<String> ids = request.getId();
String location = request.getLocation();
boolean idsCk = CollectionUtils.isNotEmpty(ids) && ids.size() > 0;
boolean locationCk = !StringUtils.isEmpty(location);
List<Customer> result;
try {
if (idsCk) {
if (locationCk) {
// use [ids location] query db
result=customerRepository.findxxx(ids,location);
} else {
// use [ids] query db
result=customerRepository.findxxx(ids);
}
} else {
if (locationCk) {
// use [location] query db
result=customerRepository.findxxx(location);
} else {
// query all record in db
result=customerRepository.findxxx();
}
}
} catch (Exception e) {
throw new SystemException();
}
return result;
}
public List<Client> retrieveEntityRecords(RequestParam request) {
List<String> ids = request.getId();
String location = request.getLocation();
boolean idsCk = CollectionUtils.isNotEmpty(ids) && ids.size() > 0;
boolean locationCk = !StringUtils.isEmpty(location);
List<Client> result;
try {
if (idsCk) {
if (locationCk) {
// use [ids location] query db
result=clientRepository.findxxx(ids,location);
} else {
// use [ids] query db
result=clientRepository.findxxx(ids);
}
} else {
if (locationCk) {
// use [location] query db
result=clientRepository.findxxx(location);
} else {
// query all record in db
result=clientRepository.findxxx();
}
}
} catch (Exception e) {
throw new SystemException();
}
return result;
}
谢邀
先来简单粗暴的。。。。竟然想把两个方法合一,很简单,其实合一的时候,就是把公共部分用同一个东西表示,楼上已有兄弟有建议用接口,是可以的,不过竟然属性和代码结构差不多,
lambda+泛型
应该就可以解决我们可以看到,那两个方法,需要归一的地方就两个
customer.getDone()
和client.getDone()
customer.setLocation("hongkong")
和client.setLocation("hongkong")
这两个地方的对应的方法分别就应该是
Predicate
和Consumer
了,所以我们可以建立这么一个公共方法execute
所以之前的两个方法
execute_customer
和execute_client
就可以改为不过不建议你这么写。。。毕竟三个参数的方法,还是很长了。。。并且
Customer
和Client
在业务上本身可能也没有啥联系,强行整合代码,只会给以后的维护带来巨大理解成本,因为它们只是恰好有两个相同的字段,恰好他们的处理模式一样但是我们可以换个角度思考,既然恰好它们有两个相同的字段,恰好他们处理模式一样,题主也想把他们合在一个方法里,那我们不看
Customer
和Client
,光看属性location
和isDone
,光看方法里if
的处理,是不是就可以说明,他们两个属性合在一起代表着一个业务,一个独立于Customer
和Client
的业务,它有自己的属性location
和isDone
,也有自己的行为,那就是if
的处理,假如我们设定这么一个业务叫Location
,那它一定可以写成这样的话,
Customer
和Client
就变成因此
Order
里的方法就变成嗯嗯,这么写,赶脚完美的雅痞,当然一切还是以实际业务来决定,我只是根据当前题主提供的信息做了一些猜想,并且写出的一种方式,实际业务可能需要调整,仅供参考,就酱
===============================小小更新==============================
评论里题主提到如何用接口来整合,其实这也是面向接口编程的小实例哈,面向接口编程,就是需要把整个业务逻辑按照接口预定义的方式组装起来,出现接口的调用的地方,即业务抽象的点
其实和之前的抽象点差不多,还是
customer.getDone()
和client.getDone()
customer.setLocation("hongkong")
和client.setLocation("hongkong")
这两个点之前用函数式接口表示的,此时用接口去表示,比如我们定义这样一个功能接口,就叫
ILocation
吧,那它可以这么表示为什么要这么写,是恰好,这两个方法的命名方式就是
Client
和Customer
中的属性set
,get
方法,这样就减少了写实现方法的必要,之后Client
和Customer
就可以这么表示因为
set
和get
方法方法都已经实现了ILocation
,用了lombok
的注解后,代码可以啥都不加了(lombok对于默认的Boolean
类型属性的get
方法是getIsDone
,所以若是需要的话,不要加is
开头)之后在
Order
那里就可以这么写一个公用方法接口实现大体就是这样,仅供参考,就酱
=============================2018-11-21新问题更新===============================
回答问题之前,还是要说明一点哈,任何代码的整合,要么是要在业务范围内可以合并,要么就是公共结构或工具抽取,过分强行的整合代码,只会胡乱增加业务之间的耦合,给后续扩展开发带来极大的不变
回到题主的新问题中,可以看到,这个时候已经不是简单靠传入参数就解决了(虽然也还是可以,不过那么写实在不太友好,也不利于扩展),这次我们可以从直接两段方法中简单抽象出这么一个业务过程
以上这段代码应该就是之前两个方法的主干代码了,也是这次要整合的业务核心代码,我们还是学上个问题一样,把公共部分抽离处理啊,其他需要具体实现的那就用接口来实现了,那具体需要实现的就是这4行注释了
那所以我们定义这么一个接口
ILocationIdsQuery
(个人理解就是按照Location和id进行查询的公共逻辑,所以这么简单取名了),它就定义有这么4个抽象方法这么定义下来,就会发现其实这和
customerRepository
和clientRepository
的接口方法一致,如果你的customerRepository
和clientRepository
没有公共的父类接口,那么这个时候你可以给它们都加个一个父类接口ILocationIdsQueryExecutor
,并补充他们的实现,如果本身customerRepository
和clientRepository
就有这么一个公共的父类接口,那就可以不用定义这么一个新接口了有了这么一个公共接口之后,那就简单了,直接开一个工具类
LocationIdsQueryUtils
(保持业务的一致性,方便其他人看看代码,所以就取了这么一个名字)那有了这么一个工具类,剩下的就好写多了,直接调用工具类即可
大体就是这样,仅供参考,就酱