如何减少项目中if-else嵌套

如何减少项目中if-else嵌套

一般建议if-else嵌套不超过三层

原始代码

Bean类

private class ShareItem{
    int type;
    String title;
    String content;
    String imagePath;
    String link;
}
public interface ShareListener{
    int STATE_SUCC=0;
    int STATE_FAIL=1;
    void onCallback(int atate,String msg);
}

定义分享接口

public void share(ShareItem item,ShareListener listener){
    if(item!=null){
        if(item.type==TYPE_LINK){
            if(!TextUtils.isEmpty(item.link)&&!TextUtils.isEmpty(item.title)){
                doShareLink(item.link,item.title,item.content,listener);
            }else{
                 if(listener!=null){
                      listener.onCallback(ShareListener.STATE_FAIL,"分享信息不完整")}
            }
        }else if(item.type==TYPE_IMAGE){
            if(!TextUtils.isEmpty(item.imagePath)){
                doShareImage(item.imagePath,listener);
            }else{
                 if(listener!=null){
                      listener.onCallback(ShareListener.STATE_FAIL,"分享信息不完整")}
            }
        }else if(item.type==TYPE_TEXT){
            if(!TextUtils.isEmpty(item.content)){
                doShareText(item.content,listener);
            }else{
                 if(listener!=null){
                      listener.onCallback(ShareListener.STATE_FAIL,"分享信息不完整")}
            }
        }else if(item.type==TYPE_IMAGE_TEXT){
            if(!TextUtils.isEmpty(item.content)&&!TextUtils.isEmpty(item.imagePath)){
                doShareImageAndText(item.imagePath,item.content,listener);
            }else{
                 if(listener!=null){
                      listener.onCallback(ShareListener.STATE_FAIL,"分享信息不完整")}
            }
        }else{
            if(listener!=null){
                listener.onCallback(ShareListener.STATE_FAIL,"不支持的分享类型")}
        }
    }else{
         if(listener!=null){
                listener.onCallback(ShareListener.STATE_FAIL,"ShareItem不能为null")}
    }
}
    

目前来看思路清晰,但share方法分支15条,意味着每次回看代码都的考虑15种情况,并把15中情况全部测试,如果增加效其他功能又要增加多条分支,还要读代码改代码。我们的脑力不该花费在无止境的分支语句里。分析代码上面代码分支原因:null判断、业务判断、状态判断

多次判断是否为null时可以接口分层

1、方法一:接口分层

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

public void share(ShareItem item,ShareListener listener){
    if(item==null){
        if(listener!=null){
             listener.onCallback(ShareListener.STATE_FAIL,"ShareItem不能为null")}
        return;
    }
    if(listener==null){
        listener=new shareListener(){
            @Override
            public void onCallback(int state,String msg){
                Log.i("DEBUG","ShareListener is null");
            }
        };
    }
    shareImpl(item,listener);
}

private void shareImpl(ShareItem item,ShareListener listener){
    if(item.type==TYPE_LIKE){
        if(!TextUtils.isEmpty(item.link)&&!TextUtils.isEmpty(item.title)){
            doShareLink(item.link,item.title,item.content,listener);
        }else{
            listener.onCallback(ShareListener.STATE_FAIL,"分享信息不完整")}
    }else if(item.type==TYPE_IMAGE){
        if(!TextUtils.isEmpty(item.imagePath)){
            doShareImage(item.imagePath,listener);
        }else{
            listener.onCallback(ShareListener.STATE_FAIL,"分享信息不完整")}
    }else if(item.type==TYPE_TEXT){
        if(!TextUtils.isEmpty(item.content)){
            doShareText(item.content,listener);
        }else{
            listener.onCallback(ShareListener.STATE_FAIL,"分享信息不完整")}
    }else if(item.type==TYPE_IMAGE_TEXT){
        if(!TextUtils.isEmpty(item.content)&&!TextUtils.isEmpty(item.imagePath)){
            doShareImageAndText(item.imagePath,item.content,listener);
        }else{
            listener.onCallback(ShareListener.STATE_FAIL,"分享信息不完整")}
    }else{
        listener.onCallback(ShareListener.STATE_FAIL,"不支持的分享类型")}
}

上面代码分为外部接口share和内部接口shareImpl,ShareItem和ShareListener的判断都放在share里完成,那么shareImpl就减少了if-else嵌套,这样嵌套就不超过3层

但shareImpl了还是包含分享类型的判断,即业务判断,分享的类型随时可能改变或添加,我们用多态解决,多态不但能应付业务改变的情况,也可以减少if-else嵌套

2、方法二:利用多态

利用多态,每种业务单独处理,在接口不再做任何业务判断。把shareItem抽象出来,作为基础类,然后针对每种业务各自实现其子类

public abstract class ShareItem {
    int type;

    public ShareItem(int type) {
        this.type = type;
    }

    public abstract void doShare(ShareListener listener);
}

public class Link extends ShareItem {
    String title;
    String content;
    String link;

    public Link(String link, String title, String content) {
        super(TYPE_LIKE);
        this.link = !TextUtils.isEmpty(link) ? link : "default";
        this.title = !TextUtils.isEmpty(title) ? title : "default";
        this.content = !TextUtils.isEmpty(content) ? content : "default";
    }

    @Override
    public void doShare(ShareListener listener) {

    }
}

public class Image extends ShareItem {
    String imagePath;

    public Image(String imagePath) {
        super(TYPE_IMAGE);
        this.imagePath = !TextUtils.isEmpty(imagePath) ? imagePath : "default";
    }

    @Override
    public void doShare(ShareListener listener) {

    }
}

public class Text extends ShareItem {
    String content;

    public Text(String content) {
        super(TYPE_TEXT);
        this.content = !TextUtils.isEmpty(content) ? content : "default";
    }

    @Override
    public void doShare(ShareListener listener) {

    }
}

public class ImageText extends ShareItem {
    String content;
    String imagePath;

    public ImageText(String imagePath, String content) {
        super(TYPE_IMAGE_TEXT);
        this.imagePath = !TextUtils.isEmpty(imagePath) ? imagePath : "default";
        this.content = !TextUtils.isEmpty(content) ? content : "default";
    }

    @Override
    public void doShare(ShareListener listener) {

    }
}

注意:上面每个子类的构造方法还对每个字段做了空值处理,为空的话,赋值default,这样如果用户传了空值,在调试就会发现问题。

实现多态后,分享接口就简单多了:

public void share(ShareItem item,ShareListener listener){
    if(item==null){
        if(listener1!=null){
            listener.onCallback(ShareListener.STATE_FAIL,"ShareItem不能为null");
        }
        return;
    }
    if(listener==null){
        listener=new ShareListener(){
            @Override
            public void onCallback(int state,String msg){
                Log.i("DEBUG","ShareListener is null");
            }
        };
    }
    shareImpl(item,listener);
}

private void shareImpl(ShareItem item,ShareListener listener){
    item.doShare(listener);
}

如果这个分享功能是自己App里的功能,不是第三方SDK,到这里已经没有问题了。但如果时第三方SDK的功能的话,这样暴漏给用户的类就增加了很多,用户的接入成本很高,违背了迪米特原则。处理这种情况也简单,再次封装一层即可。把ShareItem的子类的访问权限降低,在暴漏给用户的主类里定义几个方法,在内部帮助用户创建具体的分享类型,这样用户就无需知道具体的类了:

public ShareItem createLinkShareItem(String link,String title,String content){
    return new Link(link,title,content);
}

public ShareItem createImageShareItem(String ImagePath){
    return new Image(ImagePath);
}

public ShareItem createTextShareItem(String content){
    return new Text(content);
}

public ShareItem createImageTextShareItem(String ImagePath,String content){
    return new ImageText(ImagePath,content);
}

或者有人会说,这样用户也需要额外来了解多几个方法,其实让用户多了解几个方法好过多了解几个类,而方法名一看就知道意图,成本还是挺小的,时可以接受的。

其实这种情况,更多人想到的是工厂模式,但工厂模式用户也需要额外了解多今几个type类型,而且工厂模式难免要引入分支,我们可以用Map消除分支。

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

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

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

private void init(){
    map.put(TYPE_LINK,Link.class);
    map.put(TYPE_IMAGE,Image.class);
    map.put(TYPE_TEXT,Text.class);
    map.put(TYPE_IMAGE_LINK,ImageText.class);
}

public ShareItem creatShareItem(int type){
    try{
        Class<? extends ShareItem> shareItemClass = map.get(type);
        return shareItemClass.newInstance();
    }catch(Exception e){
        return new DafaultShareItem();
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值