在项目中遇到一个问题,就是需要根据不同参数来执行不同的算法来得到一个处理结果,来实现对不同项目需求的动态适配。
实现思路 1.策略模式+模版方法模式这种方式的难点在于策略模式如何与spring相结合,完成策略判断条件在项目启动时加载到对应的类中,这里网上有很多材料可以借鉴,就不过多阐述,推荐使用@PostConstruct注解。
只是这种方式对于业务逻辑处理起来相当方便,如果换成算法而言,就显得很不灵活。对于算法而言,它只在乎输入和输出,并不依赖于任何框架,即插即用。
- 以工具类的形式来使用算法
- 能根据对应的输入参数,动态选择不同的算法
2. 算法抽象类org.projectlombok lombok 1.18.4 org.reflections reflections 0.9.10 com.alibaba fastjson 1.2.32
package voteCalculate;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.List;
@Data
@EqualsAndHashCode
@Accessors(chain = true)
public abstract class VoteCalculateHandle {
private ValidChain chain;
private List memberDtoList;
private List voteRecordList;
public VoteCalculateResultDto calculate() {
checkParameter();
return calculateItem();
}
protected abstract void checkParameter();
protected abstract VoteCalculateResultDto calculateItem();
public void addValid(String key, Object value) {
if (chain == null){
chain = new ValidChain(key, value);
}else{
ValidChain tmp = chain;
while (tmp.getNext() != null) {
tmp = tmp.getNext();
}
tmp.setNext(new ValidChain(key, value));
}
}
}
@Data
@EqualsAndHashCode
@Accessors(chain = true)
class ValidChain {
private String key;
private Object value;
private ValidChain next;
public ValidChain(String key, Object value) {
this.key = key;
this.value = value;
}
}
3.算法实现子类
package voteCalculate;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
@Data
@EqualsAndHashCode
@Accessors(chain = true)
public class VoteCalculateOneHandle extends VoteCalculateHandle {
public VoteCalculateOneHandle() {
// 生成调用链
addValid("voteType", "0");
addValid("voteRound", 1);
}
@Override
protected void checkParameter() {
}
@Override
protected VoteCalculateResultDto calculateItem() {
VoteCalculateResultDto voteCalculateResultDto = new VoteCalculateResultDto();
voteCalculateResultDto.setVoteResultId("运行算法1");
return voteCalculateResultDto;
}
}
4.算法的入参类
package voteCalculate;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;
@Data
@EqualsAndHashCode
@Accessors(chain = true)
public class VoteCalculateParameterDto implements Serializable {
private String environmentCode;
private String voteType;
private List memberDtoList;
private List voteRecordList;
}
5.投票结论类
package voteCalculate;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@EqualsAndHashCode
@Accessors(chain = true)
public class VoteCalculateResultDto implements Serializable {
private String voteResultId;
private String voteResultTxt;
private String voteResultItem;
}
6.算法工具类
package voteCalculate;
import com.alibaba.fastjson.JSONObject;
import org.reflections.Reflections;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class VoteCalculateUtil {
public static VoteCalculateResultDto getVoteCalculateResult(VoteCalculateParameterDto parameterDto) throws Exception {
VoteCalculateHandle planDto = getPlanDto(parameterDto);
if (planDto == null) {
throw new Exception();
}
return planDto.calculate();
}
private static VoteCalculateHandle getPlanDto(VoteCalculateParameterDto parameterDto) {
List handleList = getHandleList();
for (VoteCalculateHandle handle : handleList) {
ValidChain chain = handle.getChain();
while (chain != null) {
String key = chain.getKey();
Object value = chain.getValue();
boolean validFlag = false;
try {
Field keyField = parameterDto.getClass().getDeclaredField(key);
if (keyField != null) {
// 允许访问
keyField.setAccessible(true);
Object keyValue = keyField.get(parameterDto);
if (value.equals(keyValue)) {
validFlag = true;
}
}
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
if (!validFlag) {
break;
} else {
chain = chain.getNext();
}
}
if (chain == null) {
handle.setMemberDtoList(null);
return handle;
}
}
return null;
}
public static List getHandleList() {
List list = new ArrayList<>();
Reflections reflections = new Reflections(VoteCalculateHandle.class.getPackage().getName());
Set> subTypes = reflections.getSubTypesOf(VoteCalculateHandle.class);
subTypes.forEach(x -> {
try {
VoteCalculateHandle obj = x.newInstance();
list.add(obj);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
});
return list;
}
public static void main(String[] args) {
VoteCalculateParameterDto parameterDto = new VoteCalculateParameterDto();
parameterDto.setVoteType("0").setVoteRound(1);
VoteCalculateHandle handle = getPlanDto(parameterDto);
VoteCalculateResultDto voteCalculateResultDto = handle.calculate();
System.out.println(JSONObject.toJSONString(voteCalculateResultDto));
}
}
7.代码运行



