Java:程序开发中if else多层嵌套的优化

Java:程序开发中if else多层嵌套的优化

if else作为每种编程语言都不可或缺的条件语句,我们在编程时会大量的用到。但if else一般不建议嵌套超过三层,如果一段代码存在过多的if else嵌套,代码的可读性就会急速下降,后期维护难度也大大提高。所以,程序员都应该尽量避免过多的if else嵌套。下面将会简单谈谈如何减少if else的嵌套。

业务场景:分享一条新闻的标题,内容,链接。
业务基础类:如下

private static final int TYPE_TITLE = 0;
private static final int TYPE_CONTENT = 1;
private static final int TYPE_LINK = 2;

public class NewItem {
    int type;
    String title;
    String content;
    String link;
}

public interface ShareNewListener {
    int STATE_SUCC = 0;
    int STATE_FAIL = 1;

    void onCallback(int state, String message);
}

业务实现:如下

public void share (NewItem item, ShareNewListener listener) {
    if (item != null) {
        if (item.type == TYPE_LINK) {
            // 分享链接
            if (item.link != null) {
                doShareLink(item.link, item.content, listener);
            } else {
                if (listener != null) {
                    listener.onCallback(ShareNewListener.STATE_FAIL, "分享信息不完整");
                }
            }
        } else if (item.type == TYPE_TITLE ) {
            // 分享标题
            if (item.title != null)) {
                doShareText(item.title, listener);
            } else {
                if (listener != null) {
                    listener.onCallback(ShareNewListener.STATE_FAIL, "分享信息不完整");
                }
            }
        } else if (item.type == TYPE_CONTENT) {
            // 分享内容
            if (item.content != null) {
                doShareImageAndText(item.content, listener);
            } else {
                if (listener != null) {
                    listener.onCallback(ShareNewListener.STATE_FAIL, "分享信息不完整");
                }
            }
        } else {
            if (listener != null) {
                listener.onCallback(ShareNewListener.STATE_FAIL, "不支持的分享类型");
            }
        }
    } else {
        if (listener != null) {
            listener.onCallback(ShareNewListener.STATE_FAIL, "NewItem 不能为 null");
        }
    }
}

if else嵌套一般是为了解决空值判断,业务判断,状态判断等问题。针对这些问题可以通过下述方法进行优化:

方法一:接口分层

所谓接口分层指的是:把接口分为外部和内部接口,所有空值判断放在外部接口完成,只处理一次;而内部接口传入的变量由外部接口保证不为空,从而减少空值判断。

public void share(NewItem item, ShareNewListener listener) {
    if (item == null) {
        if (listener != null) {
            listener.onCallback(ShareNewListener.STATE_FAIL, "ShareItem 不能为 null");
        }
        return;
    }

    if (listener == null) {
        return;
    }

    shareImpl(item, listener);
}

private void shareImpl(ShareItem item, ShareNewListener listener) {
    if (item.type == TYPE_LINK) {
        // 分享链接
        if (item.link != null) {
            doShareLink(item.link, item.content, listener);
        } else {
            if (listener != null) {
                listener.onCallback(ShareNewListener.STATE_FAIL, "分享信息不完整");
            }
        }
    } else if (item.type == TYPE_TITLE ) {
        // 分享标题
        if (item.title != null)) {
            doShareText(item.title, listener);
        } else {
            if (listener != null) {
                listener.onCallback(ShareNewListener.STATE_FAIL, "分享信息不完整");
            }
        }
    } else if (item.type == TYPE_CONTENT) {
        // 分享内容
        if (item.content != null) {
            doShareImageAndText(item.content, listener);
        } else {
            if (listener != null) {
                listener.onCallback(ShareNewListener.STATE_FAIL, "分享信息不完整");
            }
        }
    } else {
        if (listener != null) {
            listener.onCallback(ShareNewListener.STATE_FAIL, "不支持的分享类型");
        }
    }
}

方法二:多态

利用多态,每种业务单独处理,在接口不再做任何业务判断。

private static final int TYPE_TITLE = 0;
private static final int TYPE_CONTENT = 1;
private static final int TYPE_LINK = 2;

public abstract class NewItem {
    int type;
    String title;
    String content;
    String link;

    public NewItem(int type,String title,String content,String link) {
        this.type = type;
        this.title=title;
        this.content=content;
        this.link=link;
    }

    public abstract void doShare(ShareNewListener listener);
}

public class New_Title extends NewItem {
    String title;

    public Link(String title) {
        super(TYPE_TITLE);
        this.title = title!=null ? title : "default";
    }

    @Override
    public void doShare(ShareNewListener listener) {
         listener.onCallback(ShareNewListener.STATE_SUCC, title);
    }
}

public class New_Content extends NewItem {
    String content;

    public Link(String content) {
        super(TYPE_CONTENT);
        this.content = content!=null ? content : "default";
    }

    @Override
    public void doShare(ShareNewListener listener) {
         listener.onCallback(ShareNewListener.STATE_SUCC, content);
    }
}

public class New_Link extends NewItem {
    String link;

    public Link(String link) {
        super(TYPE_LINK);
        this.link = link!=null ? link : "default";
    }

    @Override
    public void doShare(ShareNewListener listener) {
         listener.onCallback(ShareNewListener.STATE_SUCC, link);
    }
}

public void share(NewItem item, ShareNewListener listener) {
    if (item == null) {
        if (listener != null) {
            listener.onCallback(ShareNewListener.STATE_FAIL, "ShareItem 不能为 null");
        }
        return;
    }

    if (listener == null) {
        return;
    }

    shareImpl(item, listener);
}

private void shareImpl(NewItem item, ShareNewListener listener) {
    item.doShare(listener);
}

public ShareItem createNew_TitleItem(String title) {
    return new New_Title(title);
}
public ShareItem createNew_ContentItem(String content) {
    return new New_Content(content);
}
public ShareItem createNew_LinkItem(String link) {
    return new New_LinkItem(link);
}

方法三:使用Map替代分支语句

把所有分享子类型预先缓存在Map里,那么就可以直接get获取具体类型,消除分支

private Map<Integer, Class<? extends NewItem>> map = new HashMap<>();

private void init() {
    map.put(TYPE_TITLE, Title.class);
    map.put(TYPE_CONTENT, Content.class);
    map.put(TYPE_LINK, Link.class);
}

public NewItem createNewItem(int type) {
    try {
        Class<? extends NewItem> NewItemClass = map.get(type);
        return NewItemClass.newInstance();
    } catch (Exception e) {
        return new NewItem(); // 返回默认父类,不要返回null
    } 
}

总结

1.把接口分为外部和内部接口,所有空值判断放在外部接口完成;而内部接口传入的变量由外部接口保证不为空,从而减少空值判断。

2.利用多态,把业务判断消除,各子类分别关注自己的实现,并实现子类的创建方法,避免用户了解过多的类。

3.把分支状态信息预先缓存在Map里,直接get获取具体值,消除分支。

参考:https://mp.weixin.qq.com/s/vbJi0mqxYSVchMCzZ5FOpQ

感觉自己看起来都费劲( ⊙ o ⊙ ), [code="java"] public String login() { boolean loginpass = false; Pckey pckey = null; int validate = 0; // 密码验证标识 Integer keyright = 1; HttpServletRequest request = ServletActionContext.getRequest(); String remoteIp = request.getRemoteAddr(); String localIp = request.getLocalAddr(); String passFlag = request.getParameter("validate"); if (StringUtils.isNotEmpty(passFlag)) { validate = Integer.parseInt(passFlag); } if (StringUtils.isNotEmpty(username)) { keyright = Integer.parseInt(userright); pckey = pckeyService.findKey(username, keyright); } if (pckey != null) { boolean locked = pckeyService.isLocked(pckey); if (!locked) { // 没锁定 if (pckeyService.reachMaxCount(pckey)) { pckeyService.clearErrorCount(pckey); } // 验证密码标识 if (validate == 100) { pckeyService.clearErrorCount(pckey); HttpSession session = ServletActionContext.getRequest() .getSession(); session.setAttribute("keyname", username); // 登录名 session.setAttribute("keyright", userright); // 登录权限 Calendar c = Calendar.getInstance(); c.add(Calendar.HOUR_OF_DAY, 10); session.setAttribute("logintime", c.getTime().toString()); // 登录时间 loginpass = true; } else { int errorCount = pckeyService.addErrorCount(pckey); if (errorCount > 0) { msg = "用户名或密码错误,剩余" + errorCount + "次key将被锁定"; } else { msg = "用户名或密码错误,此key已被限制登陆!"; pckeyService.setLockDate(pckey); } } } else { // 锁定 msg = "此key已经被锁定,您无法登陆系统"; } } else { // key 不合法 msg = "请插入合法key"; } // 添加审计日志 auditlogService.addAuditlog(remoteIp, username, localIp, 1, 1, loginpass == true ? "登录系统成功!" : "登陆系统失败", 1); return loginpass == true ? SUCCESS : "error"; } [/code] [code="java"] private List<AuditlogVO> queryFromlist(List<AuditlogVO> list) { List<AuditlogVO> sublist = new ArrayList<AuditlogVO>(); if (list == null || list.size() == 0) { return null; } for (AuditlogVO vo : list) { if (StringUtils.isNotEmpty(startTime)) { long starttime = DateUtils.date2LongNumber(startTime); long createdate = DateUtils.date2LongNumber(vo.getCreatedate()); if (starttime > createdate) continue; } if (StringUtils.isNotEmpty(endTime)) { long endtime = DateUtils.date2LongNumber(endTime); long createdate = DateUtils.date2LongNumber(vo.getCreatedate()); if (createdate > endtime) continue; } if (StringUtils.isEmpty(logType) || logType.equals("全部") || logType.equals(vo.getTypename())) { if (StringUtils.isEmpty(logaction) || logaction.equals("全部") || logaction.equals(vo.getActionname())) { if (StringUtils.isEmpty(logLevel) || logLevel.equals("全部") || logLevel.equals(vo.getLevelname())) { if (StringUtils.isEmpty(logResult) || logResult.equals("全部") || logResult.equals(vo.getResult())) { if (StringUtils.isEmpty(subname) || subname.equals(vo.getSubname())) { if (StringUtils.isEmpty(from) || from.equals(vo.getAddress())) { if (StringUtils.isEmpty(targetIp) || targetIp.equals(vo.getObjname())) { sublist.add(vo); } } } } } } } } return sublist; } [/code]
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页