闽公网安备 35020302035485号


if(condition){
//doSomething
}else{
}
return;
优化后如下:if(!condition){
return;
}
二、能省则省,规避最后的elsepublic Result addUser() {
if (StrUtil.equals(userStatus, "online")) {
return doStep1();
} else {
return doStep2();
}
// else 后面没有其他业务时,可省略最后的else,使代码简洁
}
优化后的代码:public Result addUser() {
if (StrUtil.equals(userStatus, "online")) {
return doStep1();
}
return doStep2();
}
当然这里面要注意的点是,一定要确认是最后的else,并没有其他的业务逻辑。public Result addUser() {
return StrUtil.equals(userStatus, "online")) ?doStep1() : doStep2();
}
一个方法一行代码搞定。if (user == null) {
throw new Exception("未查询到用户信息");
}
if (user != null) {
update(user); // 执行方法调用
}
代码优化后:Optional.ofNullable(user).orElseThrow(() -> new Exception("未查询到用户信息"));
Optional.ofNullable(user).ifPresent(user -> update(user));
隐式调用相当优雅。public void addUser(User user) {
// 1.非空校验
if (StrUtil.isBlank(user.getUsername())) {
throw new RuntimeException("用户名为空!");
}
if (StrUtil.isBlank(user.getPassword())) {
throw new RuntimeException("密码为空!");
}
...
// 2.格式校验
if (!ValidUtil.isIdCardNo(user.getIdCardNo())) {
throw new RuntimeException("身份证号格式错误!");
}
if (!ValidUtil.isEmail(user.getEmail())) {
throw new RuntimeException("手机号格式错误!");
}
if (!ValidUtil.isEmail(user.getEmail())) {
throw new RuntimeException("邮箱格式错误!");
}
...
// 3.要四素认证校验
if(!doFourStampVerify(User user)){
throw new RuntimeException("四要素认证失败!");
}
}
此处可能还有很多其他的省略的场景。所以单个文件中的If else可能比想象中多的多。那么我们如何用责任链模式进行优化呢?/**
* 处理器链接口
*/
public interface UserChainHandler {
void handler(User user);
}
剩下不同的场景校验只要去实现这个接口就可以了,不过需要定义好顺序@Component
@Order(1) // 指定注入顺序
public class UserParamNullValidChainHandler implements UserChainHandler {
@Override
public void handler(User user) {
// 1.非空校验
if (StrUtil.isBlank(user.getUsername())) {
throw new RuntimeException("用户名为空!");
}
if (StrUtil.isBlank(user.getPassword())) {
throw new RuntimeException("密码为空!");
}
}
@Component
@Order(1) // 指定注入顺序
public class UserParamNullValidChainHandler implements UserChainHandler {
@Override
public void handler(User user) {
// 1.非空校验
if (StrUtil.isBlank(user.getUsername())) {
throw new RuntimeException("用户名为空!");
}
...
}
/**
* 格式校验处理器
*/
@Component
@Order(2) // 指定注入顺序
public class UserParamFormatValidChainHandler implements UserChainHandler {
@Override
public void handler(User user) {
// 2.格式校验
if (!ValidUtil.isIdCardNo(user.getIdCardNo())) {
throw new RuntimeException("身份证号格式错误!");
}
...
}
/**
* 四要素处理器
*/
@Component
@Order(3) // 指定注入顺序
public class FourElementVerifyChainHandler implements UserChainHandler {
@Override
public void handler(User user) {
// 2.格式校验
if (!doFourStampVerify(User user)) {
throw new RuntimeException("四要素认证失败!");
}
}
//进行组装
@Component
@RequiredArgsConstructor
public class UserChainContext {
private final List<UserChainHandler> userChainHandlerList; // 自动注入责任链处理器
/**
* 责任链组件执行
*
* @param requestParam 请求参数
*/
public void handler(User user) {
// 此处根据 Ordered 实际值进行排序处理
userChainHandlerList.forEach(x -> x.handler(user));
}
}
最终咱们的原来的add方法进行这样调用就好了public void addUser(User user) {
// 执行责任链
userChainContext.handler(user);
}
第二种,合理使用策略模式+工厂模式。public Result calcPrice(CalcPriceParam calcPriceParam){
//判断对应的计算价格的场景
Integer type = judgeType(calcPriceParam);
//根据场景调用不同的方法 ,建议更好的编码习惯是把type改成枚举类型哈~
if(type == 1){
return calcPriceForTypeOne();
}
if(type == 2){
return calcPriceForTypeTwo();
}
if(type == 3){
return calcPriceForTypeThree();
}
.....
if(typr == 10){
return calcPriceForTypeTen();
}
}
显而易见随着会员价格场景套餐越来越多,我们的if也会越来越多。public interface Strategy {
Result calcPrice(CalcPriceParam calcPriceParam);
int getBizType();
}
@Service
public Class firstStragy implement Strategy {
Result calcPrice(CalcPriceParam calcPriceParam) {
....
return result;
}
int getBizType() {
return 1;
}
}
public Class secondStragy implement Strategy {
Result calcPrice(CalcPriceParam calcPriceParam) {
....
return result;
}
int getBizType() {
return 2;
}
}
@Service
public class StrategyContext{
Map<Integer,CalcPriceInterface> strategyContextMap = new HashMap<>();
//注入对应的策略类
@Autowired
Strategy[] strategys;
@PostConstruct
public void setStrategyContextMap(){
for(Stragegy stragegy:strategys){
strategyContextMap.put(stragegy.getCode,stragegy);
}
}
//根据场景调用不同的方法
public Result calcPrice(CalcPriceParam calcPriceParam){
Integer type = judgeType(calcPriceParam);
CalcPriceInterface calcPriceInstance = strategyContextMap.get(type);
return calcPriceInstance.calcPrice(calcPriceParam);
}
}
这样一来,咱们上面的第一个方法中的If else的实现将会变得很简单,如下:@Autowired
StrategyContext strategyContext;
public Result calcPrice(CalcPriceParam calcPriceParam){
strategyContext.calcPrice(calcPriceParam);
}
这样即使新增新的计算模式,我们只需去实现Strategy接口并且重写里面两个方法即可完成后续业务的拓展。代码优雅简单,可维护性强。Map<String, Function<?> action> actionMap = new HashMap<>();
action.put("type1",() -> {calcPriceForTypeOne()});
action.put("type2",() -> {calcPriceForTypeTwo()});
action.put("type3",() -> {calcPriceForTypeThree()});
...
// 使用
actionMap.get(action).apply();
当然如果想要再优化得好一些的话,可以进行接口抽取,然后进行实现,在此不展开,留下给小伙伴们思考一下。if(status.equals(1)){
return "订单未支付";
}else if(status.equals(2)){
return "订单已支付"
}else if(status.equals(3)){
return "订单已发货"
}
.....
优化后@Getter
@AllArgsConstructor
public enum OrderStatusEnum {
UN_PAID("1","订单未支付"),
PAIDED("2","订单已支付"),
SENDED("3","订单已发货"),
.....;
private String status;
private String statusDes;
static OrderStatusEnum of(String status) {
for (OrderStatusEnum statusEnum : OrderStatusEnum.values()) {
if (statusEnum.getStatus().equals(status)) {
return statusEnum;
}
}
return null;
}
}
String orderStatusDes = OrderStatusEnum.of(orderStatus).getStatusDes();
等等还有其他一些,由于这些优化个人认为是没法标准化的优化原则,不同的业务场景都不同,所以在此,老猫不将其放在通用优化中,认为这个是其他优化方式。3.虽然经过好几轮研发之手,有的研发害怕改出业务问题,所以选择继续堆屎山。