动车,作为一位Java开发者当我看到一堆if else时我的心里是奔溃的,昆虫记

不知咱们有没遇到过像“横放着的金字塔”相同的if else嵌套:

if (true) {
if (true) {
if (true) {
if (true) {
if (true) {
if (true) {
}
}
}
}
}
}

我并没言过其实,我是真的遇到过了!嵌套6、7层,一个函数几百行,简!直!看!死!人!

if else作为每种编程言语都不可或缺的条件句子,咱们在编程时会许多的用到。但if else一般不主张嵌套超越三层,假如一段代码存在过多的if else嵌套,代码的可读性就会急速下降,后期保护难度也大大进步。所以,咱们程序员都应该尽量防止过多的if else嵌套。下面将会谈谈我在工作中怎样削减if else嵌套的。

正文

在谈我的办法之前,无妨先用个例子来阐明if else嵌套过多的坏处。

幻想下一个简略共享的事务需求:支撑共享链接、图片、文本和图文,共享成果回调给用户(为了不跑题,这儿简略了事务,实践杂乱得多)。当接手到这么一个事务时,是不是觉得很简略,稍动下脑就能够着手了:

先界说共享的类型、共享Bean和共享回调类:

private static final int TYPE_LINK = 0;
private static final int TYPE_IMAGE = 1;
private static final int TYPE_TEXT = 2;
private static final int TYPE_IMAGE_TEXT = 3;
public class ShareItem {
int type;
String title;
String content;
String i农家菜magePath;
String link;
}
public interface ShareListener {
int STATE_SUCC = 0;
int STATE_FAIL = 1;
void onCallback(int state, String msg);
}

好了,然后在界说个共享接口,对每种类型别离进行共享就ok了:

public void share (ShareItem item, ShareListener listener动车,作为一位Java开发者当我看到一堆if else时我的心里是奔溃的,昆虫记) {
if (item != null) {
if (item.type == TYPE_LINK) {
// 共享链接
if (!TextUtils.isEmpty(item.link) && !TextUtils.isEmpty(item.title)) {
doShareLink(iseventem.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.imagePath) && !TextUtils.isEmpty(item.content)) {
doShareImageAndText(item.imagePath, item.content, listener);
} else {
if (listener != null) {
l话费查询istener.onCallback(ShareListener.STATE_FAIL, "共享信息不完整");
}
}
} else {
if (listener != null) {
listener.onCallback(ShareListener.STATE_FAIL, "不支撑的共享类型");
}
}
} else {
if (listener != null) {
listener.onCallback(ShareListener.STATE_F谢AIL, "ShareItem 不能为 null");
}
}
}

到此,简略的共享模型就做出来了。有没问题?老实说,假如没什么寻求的话,还真没什么问题,至少思路是明晰的。但一周后呢?一个月后呢?或许一年后呢?share办法的分支有15条,这意味着你每次回看代码得让自己的大脑变成微型的处理器,考虑15种状况。假如呈现bug,你又得考虑15种状况,并15种状况都要测验下。再假如现在需求加多共享小视频功用,你又得增加多3个分支,还要改代码,一点都不“敞开-闭合”。再再假如后边项目交代给别人跟进,别人又胡然要把自己大脑变成处理器来想每个分支的效果,我敢必定有百分之八十的人都会吐槽代码。

咱们程序员的脑力不应该花费在无止境的分支句子里的,应该专心于事务自身。所以咱们很有必要防止写出多分支嵌套的句子。好的,咱们来剖析下上面的代码多分支的原因:

空值判别

事务判别

状况判别

几乎一切的事务都离不开这几个判别,然后导致if else嵌套过多。那是不是没办法处理了?答案必定不是的。

上面的代码我是用java写的,关于java程序员来说,空值判别几乎使人很懊丧,让人身心疲乏。上面的代码每次回调都要判别一次listener是否为空,又要判别用户传入的ShareItem是否为空,还要判别ShareItem里边的字段是否动车,作为一位Java开发者当我看到一堆if else时我的心里是奔溃的,昆虫记为空......

关于这种状况,我选用的办法很简略:接口分层。

削减 if else 办法一:接口分层

所谓接口分层指的是:把接口分为外部和内部接口,一切空值判别放在外部接口完结,只处理一次;而内部接口传入的变量由外部接口确保不为空,然后削减空值判别。

来,看代码愈加直观:

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 n动车,作为一位Java开发者当我看到一堆if else时我的心里是奔溃的,昆虫记ull");
}
};
}
shareImpl(item, listener);
}
private void shareImpl (ShareItem item, ShareListener listener) {
if (item.type == TYPE_LINK) {
// 共享链接
if (!TextUtils.isEmpty(item.link) && !TextUtils.isEmpty(item.title)) {
doShareLink(item.link, item.title, item.conte眭姓怎样读nt, 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.imagePath) && !TextUtils.isEmpty(item.content)) {
doShareImageAndText(item.imagePa玫瑰花折纸th, item.content, listener);
} else {
listener.onCallback(ShareListener.STATE_FAIL, "共享信息不完整");
}
} else {
listener.onCallback(ShareListener.STATE_FAIL, "不支撑的共享类型");
}

能够看到,上面的代码分为外部接口share和内部接口shareImpl,ShareItem和ShareListener的判别都放在share里完结,那么shareImpl就削减了if else的嵌套了,相汤姆费尔顿出柜当于把if else分摊了。这样一来,代码的可读性好许多,嵌套也不超越3层了。

但能够看到,shareImpl里仍是包括共享类型的判别,也即事务判别,咱们都清楚产品司理的脑洞有多大了,共享的类型随时会改动或增加。嗯提到这儿信任咱们都想到用多态了。多态不但能敷衍事务改动的状况,也能够用来削减if else的嵌套。

削减 if else 办法二:多态

运用多态,每种事务独自处理,在接口不再做任何事务判别。把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_LINK);
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) {
// do share
}
}
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) {
// do share
}
}
public小白杨 class Text extends ShareItem {
String content;
public Text(String content) {
super(TYPE动车,作为一位Java开发者当我看到一堆if else时我的心里是奔溃的,昆虫记_TEXT);
this.content = !TextUt动车,作为一位Java开发者当我看到一堆if else时我的心里是奔溃的,昆虫记ils.isEmpty(content) ? content : "default";
}
@Override
public void doShare(ShareListener listener) {
// do share
}
}
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) {
// do share
}
}

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

完结了多态后,共享接口的就简练多了:

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 = ne正w 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);
}

嘻嘻,怎样,内部接口一个if else都没了,是不是很帅~ 假如这个共享功用是自己App里边的功用,不是第三方SDK,到这儿现已没问题了。但如我爱罗果是第三方共享SDK的功用的话,这样露出给用户的类增加了许多(各ShareItem的子类,相当于把if else抛给用户了),用户的接入本钱进步,违反了“迪米特准则”了。

处理这种状况也很简略,再次封装一层即可。把ShareItem的子类的拜访权限汪金玉下降,在露出给用户的主类里界说几个办法,在内部协助用户创立详细的共享类型,这样用户就无需知道详细的类了:

public ShareItem createLinkShareItem(String link, String title,动车,作为一位Java开发者当我看到一堆if else时我的心里是奔溃的,昆虫记 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消除分支。

削减草避图r if else 办法三:运用Map代替分支句子

把一切共享类型预先缓存在Map里,那么就能够直接get获取详细类型,消除分支:

private Map<>();
p人之初rivate void init() {
map.put(TYPE_LINK, Link.class);
map.put(TYPE_IMAGE, Image.class);
map.put(TYPE_TEXT, Text.class);
map.put(TYPE_IMAGE_TEXT, ImageText.class);
}
public ShareItem createShareItem(int type) {
try {
Class
return shareItemClass.newInstance();
} catch (Exception e) {
return new DefaultShareItem(); // 回来默许完结,不要回来null
}
}

这种办法跟上面分为几个办法的办法各有利弊,看咱们取舍了~

写在最终

讲到这儿咱们有没收成呢?总结下削减if else的办法

把接口分为外部和内部接口,一切空值判别放在外部接口完结;而内部接口传入的变量由外部接口确保不为空,然后削减空值判别。

运用多态,把事务判别消除,各子类别离重视自己的完结,并完结子类的创立办法,防止用户了解过多的类。

把分支状况信息预先缓存在Map里,直接get获取详细值,消除分支。

好了,到此就介绍完了,期望咱们i7今后写代码能留意,有则避之,无则加动车,作为一位Java开发者当我看到一堆if else时我的心里是奔溃的,昆虫记勉。期望咱们写的代码越来越简练~

重视我:私信回复“555”获取往期Java高档架构材料、源码、笔记、视频Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并发等架构技能往期架构视频截图