Ⅰ.前言
前些天在简书上看了 “if嵌套优化” 的一文章,觉得蛮实用的也挺好玩的,抱着学习的心态看了几遍,之后又给敲了一遍,然后就有了下面的纯代码笔记
学习博客: https://www.jianshu.com/p/57c065b124c4
Ⅱ.笔记
1.以微信分享来说,可以进行图片、文字、图文、链接、音乐等分享,假设这套SDK是我们写的,或许会这么写,一堆的if嵌套:
package com.wyk.ifelse;
public class IfElse01 {
private static final int TYPE_LINK = 0;
private static final int TYPE_TEXT = 1;
private static final int TYPE_IMAGE = 2;
private static final int TYPE_IMAGE_TEXT = 3;
static 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 state,String msg);
}
public static ShareItem createShareItem() {
return new ShareItem();
}
//分享的操作
public static 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.imagePath) && !TextUtils.isEmpty(item.content)) {
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");
}
}
}
}
2.上面是不是一堆的if-else嵌套,这样子不仅不美观,而且维护成本也很高,如果是作为SDK,更不能用这种形式来写,接着以 “开设内外接口的方式来减少if-else”:
package com.wyk.ifelse;
import com.wyk.ifelse.IfElse01.ShareItem;
import com.wyk.ifelse.IfElse01.ShareListener;
public class IfElse02 {
private static final int TYPE_LINK = 0;
private static final int TYPE_TEXT = 1;
private static final int TYPE_IMAGE = 2;
private static final int TYPE_IMAGE_TEXT = 3;
//外接口
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) {
//System.out.println("state : " + state + ", msg : " + msg);
}
};
}
shareImpl(item,listener);
}
//内接口
public 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.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.imagePath) && !TextUtils.isEmpty(item.content)) {
doShareImageAndText(item.imagePath, item.content, listener);
} else {
listener.onCallback(ShareListener.STATE_FAIL, "分享信息不完整");
}
} else {
listener.onCallback(ShareListener.STATE_FAIL, "不支持的分享类型");
}
}
}
3.上面这样将listener是否为null,单独在外接口里判断,确实使得内接口减少了if-else嵌套,但减少得也不多,还是好几层if-else,接着 用Java”多态” 的特性来玩玩:
package com.wyk.ifelse.sdk;
import com.wyk.ifelse.IfElse01.ShareListener;
public class IfElse03 {
private static final int TYPE_LINK = 0;
private static final int TYPE_TEXT = 1;
private static final int TYPE_IMAGE = 2;
private static final int TYPE_IMAGE_TEXT = 3;
public static abstract class ShareItem{
int type;
public ShareItem(int type) {
this.type = type;
}
public abstract void doShare(ShareListener listener);
}
//分享链接
public static class Link extends ShareItem{
String mLink;
String mTitle;
String mContent;
public Link(String link,String title,String content) {
super(TYPE_LINK);
this.mLink = (link !=null && link !="")? link : "default";
this.mTitle = (title != null && title != "")? title : "default";
this.mContent = (content != null && content != "")? content : "default";
}
@Override
public void doShare(ShareListener listener) {
if(listener == null) {
return;
}
if(mLink == "default" || mTitle == "default" || mContent == "default") {
listener.onCallback(ShareListener.STATE_FAIL, "分享信息不完整");
return;
}
listener.onCallback(ShareListener.STATE_SUCC, "链接 分享成功3");
}
}
//分享图片
public static class Image extends ShareItem{
String imagePath;
public Image(String imagePath) {
super(TYPE_IMAGE);
this.imagePath = (imagePath != null && imagePath != "")? imagePath : "default";
}
@Override
public void doShare(ShareListener listener) {
//TODO
}
}
//分享文字
public static class Text extends ShareItem{
String content;
public Text(String content){
super(TYPE_TEXT);
this.content = (content != null && content != "")? content : "default";
}
@Override
public void doShare(ShareListener listener) {
//TODO
}
}
//分享图文
public static class ImageText extends ShareItem{
String imagePath;
String content;
public ImageText(String imagePath, String content){
super(TYPE_IMAGE_TEXT);
this.imagePath = (imagePath != null && imagePath != "")? imagePath : "default";
this.content = (content != null && content != "")? content : "default";
}
@Override
public void doShare(ShareListener listener) {
//TODO
}
}
////////////////////////////////////////////////////////////////////////////
//分享的操作
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) {
System.out.println("ShareListener is null");
}
};
}
shareImpl(item, listener);
}
public void shareImpl(ShareItem item,ShareListener listener) {
item.doShare(listener);
}
}
这下子终于没看到多层if-else嵌套咯,把ShareItem进行抽象,然后供子类继承并各自实现操作,不好的是使用者得清楚哪些类对应哪些操作,才能创建类从而执行相应的操作,比如Link类是对应的链接分享,ImageText类是对应的文字分享等,这个就不太好了,怎么解决呢?
缺点:多个类对外开放,如果是sdk的形式给使用者使用,也不太友好;
解决:可以使用单独一个类来管理创建这些类,然后提供方法出来,下面列举.
public class IfElse031 {
public ShareItem createLinkShareItem(String link,String title,String content) {
return new IfElse03.Link(link,title,content);
}
public ShareItem createImageShareItem(String imagePath) {
return new IfElse03.Image(imagePath);
}
public ShareItem createTextShareItem(String content) {
return new IfElse03.Text(content);
}
public ShareItem createImageTextShareItem(String imagePath, String content) {
return new IfElse03.ImageText(imagePath,content);
}
}
4.就类似于上面这么解决,单独的一个类来管理这些子类,从而方便开发者进行调用。 另外,也可以单独提供type的形式来调用这些类,那么就得用map来进行type和子类的对应,所以:
/**
* 作用:常量类,用于提供常量
*/
public class Constant {
public static final int TYPE_LINK = 0;
public static final int TYPE_TEXT = 1;
public static final int TYPE_IMAGE = 2;
public static final int TYPE_IMAGE_TEXT = 3;
}
public abstract class ShareItem {
int type;
//List<String> args;
public ShareItem(int type) {
this.type = type;
}
public ShareItem() {
}
public void isCanShare(ShareListener listener) {
if(listener == null){
return;
}
doShare(listener);
}
abstract void doShare(ShareListener listener);
/*public void setList(List args) {
this.args = args;
}*/
}
public class Link extends ShareItem {
String mLink;
String mTitle;
String mContent;
public Link() {
}
public Link(String link,String title,String content) {
super(Constant.TYPE_LINK);
this.mLink = (link !=null && link !="")? link : "default";
this.mTitle = (link != null && link != "")? link : "default";
this.mContent = (link != null && link != "")? link : "default";
}
@Override
public void doShare(ShareListener listener) {
//TODO
}
}
public class Text extends ShareItem {
String content;
public Text() {
}
public Text(String content){
super(Constant.TYPE_TEXT);
this.content = (content != null && content != "")? content : "default";
}
@Override
public void doShare(ShareListener listener) {
//TODO
}
}
public class Image extends ShareItem {
String imagePath;
public Image() {
}
public Image(String imagePath) {
super(Constant.TYPE_IMAGE);
this.imagePath = (imagePath != null && imagePath != "")? imagePath : "default";
}
@Override
public void doShare(ShareListener listener) {
//TODO
}
}
public class ImageText extends ShareItem {
public String imagePath;
public String content;
public ImageText(String imagePath, String content){
super(Constant.TYPE_IMAGE_TEXT);
this.imagePath = (imagePath != null && imagePath != "")? imagePath : "default";
this.content = (content != null && content != "")? content : "default";
}
public ImageText() {
}
@Override
public void doShare(ShareListener listener) {
if(listener == null) {
return;
}
if(imagePath == "default" || content == "default") {
listener.onCallback(ShareListener.STATE_FAIL, "分享信息不完整");
return;
}
listener.onCallback(ShareListener.STATE_SUCC, "链接 分享成功4 : IMAGE_PATH=" + imagePath + ",CONTENT=" + content);
}
}
/**异常处理*/
public class DefaultShareItem extends ShareItem {
public DefaultShareItem() {
super(-1);
System.out.println("捕获到了异常");
}
@Override
void doShare(ShareListener listener) {
//TODO
}
}
/**提供给开发调用的类*/
public class Demo01 {
private Map<Integer,Class<? extends ShareItem>> shareMaps = new HashMap<Integer,Class<? extends ShareItem>>();
private void init() {
shareMaps.put(IfElse04.TYPE_LINK, Link.class);
shareMaps.put(IfElse04.TYPE_TEXT, Text.class);
shareMaps.put(IfElse04.TYPE_IMAGE, Image.class);
shareMaps.put(IfElse04.TYPE_IMAGE_TEXT, ImageText.class);
shareMaps.put(IfElse04.TYPE_LINK, Link.class);
}
public ShareItem createShareItem(int type){
if(shareMaps.size() == 0) {
init();
}
try {
Class<? extends ShareItem> cls = shareMaps.get(type);
return cls.newInstance();
}catch (IllegalAccessException e) {
//e.printStackTrace();
System.out.println("IllegalAccessException");
return new DefaultShareItem();
}catch (InstantiationException e) {
//e.printStackTrace();
System.out.println("InstantiationException");
return new DefaultShareItem();
}
}
}
上面每种方法都各有优缺点,用map来存储type和操作类的形式,虽不用维护多个类,也使得多个类不用对外开放,但是却还得设置各个类应有的参数(这个在上面未实现),设置参数的方法可以写在ShareItem抽象类,也可以写在子类(调用的时候得将基类强转为对应子类)。
个人觉得还是上面第三种比较好用,使用多态来控制多个类,从而避免if-else,再另外单独的类来管理这些子类,从而方便开发者进行调用
下面这个是Main类,主要调用上面的各个方法进行测试
/**
* 作用:测试IF优化的主类
*/
public class Main {
public static void main(String[] args) {
//test1();
//test2();
//test3();
test4();
}
public static void test1() {
//第一种情况(原始的if-else嵌套)
//IfElse01.ShareItem item = new IfElse01.ShareItem();
ShareItem item = IfElse01.createShareItem();
ShareListener listener = new ShareListener() {
@Override
public void onCallback(int state, String msg) {
//TODO
System.out.println("state : " + state + ", msg : " + msg);
}
};
IfElse01.share(item,listener);
}
public static void test2() {
//第二种情况(内外接口的方式来减少if-else)
ShareItem item = IfElse01.createShareItem();
ShareListener listener = new ShareListener() {
@Override
public void onCallback(int state, String msg) {
//TODO
System.out.println("state : " + state + ", msg : " + msg);
}
};
IfElse02 ifElse02 = new IfElse02();
ifElse02.share(item, listener);
}
public static void test3() {
//第三种情况(多态,缺点:多个类对外开放,可以单独一个类来提供这些类,然后提供方法出来让使用者获取)
ShareListener listener = new ShareListener() {
@Override
public void onCallback(int state, String msg) {
//TODO
System.out.println("state : " + state + ", msg : " + msg);
}
};
/*IfElse03 ifElse03 = new IfElse03();
IfElse03.ShareItem item1 = new IfElse03.Link("http://www.baidu.com","标题","内容");
ifElse03.share(item1, listener);*/
IfElse031 ifElse031 = new IfElse031();
com.wyk.ifelse.sdk.IfElse03.ShareItem linkShareItem = ifElse031.createLinkShareItem("http://www.baidu.com","标题","内容");
linkShareItem.doShare(listener);
}
public static void test4() {
//第四种情况(封装成SDK的形式 + 使用map来维护多个类),缺点,
ShareListener listener = new ShareListener() {
@Override
public void onCallback(int state, String msg) {
//TODO
System.out.println("state : " + state + ", msg : " + msg);
}
};
///////////////////////////////////////////////////////////////////////////
/*IfElse041 ifElse041 = new IfElse041();
//ifElse041.doShare(IfElse04.TYPE_IMAGE_TEXT, listener);
com.wyk.ifelse.sdk.IfElse04.ShareItem shareItem = ifElse041.createShareItem(IfElse04.TYPE_IMAGE_TEXT);
shareItem.isCanShare(listener);*/
/////////////////////////////////////////////////////////////////////////
Demo01 demo01 = new Demo01();
com.wyk.ifelse.sdk.test.ShareItem shareItem1 = demo01.createShareItem(Constant.TYPE_IMAGE_TEXT);
/**设置参数 方法1,缺点:还得用户熟悉设置参数的步骤*/
/*String[] args = new String[]{"http://www.sohu.com","内容"};
shareItem1.setList(Arrays.asList(args));*/
/**设置参数 方法2, 缺点:不人性化,还得用户转*/
ImageText imageText = (ImageText)shareItem1;
imageText.imagePath = "http://www.kugou.com";
imageText.content = "内容";
imageText.isCanShare(listener);
}
}
Ⅲ.总结
微信的分享、友盟的集成分享也是基于上面第三种方式和第四种方式,各有好处吧~ 看看SDK封装代码,可以减少代码的维护成本,从而提高代码的质量. 感谢简书该作者的分享.
上面的代码地址: https://github.com/XK-one/IfTest
声明:如有侵权,请告知删除.