如何避免一连串的if else

 我来答
AI产品狙击手
2021-05-15
知道答主
回答量:64
采纳率:100%
帮助的人:3.4万
展开全部

有网友问怎么减少代码中的if else。这里我尝试用直白的语言说清楚什么是策略模式及OCP原则,以及策略模式的应用,怎么解决纷乱的if else不容易扩展的问题…

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
天顺祥白事
2018-08-04 · TA获得超过1743个赞
知道大有可为答主
回答量:2126
采纳率:93%
帮助的人:1335万
展开全部
0x01 为什么要去if else
在开发的过程中我们可能会经常遇到if else的逻辑,写很多if else对于一位有情怀的程序员看来是不可以接收的,也影响阅读人的阅读感受,同时程序也违背了对修改关闭扩展开放的原则。在写程序的过程中我们应该尽量保证修改关闭,也就是说自己的写的代码逻辑应不该让别人在扩展逻辑的过程中进行修改,同时保证高的可扩展性。
在使用if else写程序的过程中你可能会写出如下的代码:
String strategy = "";
if(strategy.equals("策略一")){

}else if(strategy.equals("策略二")){

}else if(...){

}else {

}

当需要加一个分支逻辑就必须得去if else结构中改代码,这样不利于程序扩展,同时也非常难维护,如果业务复杂到一定的程度这块代码可能没法去重构了。
0x02 策略模式 + 工厂模式 + 单例模式
在想到要去掉if else这种结构来写代码,首先容易想到的是通过一个map来保存key对应的逻辑,作为一个从c++转到java开发的程序的思维是通过函数指针来解决问题,但是java并没有这么个东西,所以就有了下面这段代码逻辑了。
public class StrategyTest {

public static void main(String[] args) {
String result = ObtainStrategyInfo.getInstance().getStrategyInfo("策略一");
System.out.println(result);
}
}

/* (单例模式) */
class ObtainStrategyInfo {

private static final ObtainStrategyInfo obtainStrategyInfo = new ObtainStrategyInfo();

public static ObtainStrategyInfo getInstance(){
return obtainStrategyInfo;
}

public String getStrategyInfo(String strategy){
StrategyInfo strategyInfo = new StrategyFactory().getStrategyInfoClass(strategy);
return strategyInfo.getStrategyInfo(strategy);
}
}
这种单例模式在类一加载的时候就将单例对象创建完毕,总是这个对象存在内存中,避免了通过线程同步来生成对象,线程安全的创建方式。

/* 其实最终的if else判断逻辑都在这里了 (工厂模式)*/
class StrategyFactory {
private static Map<String, StrategyInfo> strategyInfoMap = new HashMap<String, StrategyInfo>();

static {
strategyInfoMap.put("策略一", new Strategy1());
strategyInfoMap.put("策略二", new Strategy2());
}

public StrategyInfo getStrategyInfoClass(String strategy){
StrategyInfo strategyInfo = null;
for(String key : strategyInfoMap.keySet()){
if(strategy.equals(key)) {
strategyInfo = strategyInfoMap.get(key);
}
}
return strategyInfo;
}
}

/* (策略模式) */
interface StrategyInfo {
String getStrategyInfo(String strategy);
}

class Strategy1 implements StrategyInfo {

public String getStrategyInfo(String strategy) {
return strategy;
}
}

class Strategy2 implements StrategyInfo {

public String getStrategyInfo(String strategy) {
return strategy;
}
}

如果需要扩展策略三,是不是只要添加自己的逻辑代码就行了呢?保证对修改关闭?答案是肯定的。可以如下方式来扩展策略三:
/* 在StrategyFactory中注入策略三的对应关系 */
strategyInfoMap.put("策略三", new Strategy3());

/* 然后定义策略三 */
class Strategy3 implements StrategyInfo {

public String getStrategyInfo(String strategy) {
return strategy;
}
}

这样可非常方便的扩展策略四、策略五。
本回答被网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
匿名用户
2018-02-25
展开全部
用case 语句?
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
EvenHHZ
推荐于2018-02-25 · 知道合伙人软件行家
EvenHHZ
知道合伙人软件行家
采纳数:13691 获赞数:18845
个人出版图书:《玩转Python网络爬虫》、《玩转Django2.0》

向TA提问 私信TA
展开全部
0x01 为什么要去if else
在开发的过程中我们可能会经常遇到if else的逻辑,写很多if else对于一位有情怀的程序员看来是不可以接收的,也影响阅读人的阅读感受,同时程序也违背了对修改关闭扩展开放的原则。在写程序的过程中我们应该尽量保证修改关闭,也就是说自己的写的代码逻辑应不该让别人在扩展逻辑的过程中进行修改,同时保证高的可扩展性。
在使用if else写程序的过程中你可能会写出如下的代码:
String strategy = "";
if(strategy.equals("策略一")){

}else if(strategy.equals("策略二")){

}else if(...){

}else {

}

当需要加一个分支逻辑就必须得去if else结构中改代码,这样不利于程序扩展,同时也非常难维护,如果业务复杂到一定的程度这块代码可能没法去重构了。
0x02 策略模式 + 工厂模式 + 单例模式
在想到要去掉if else这种结构来写代码,首先容易想到的是通过一个map来保存key对应的逻辑,作为一个从c++转到java开发的程序的思维是通过函数指针来解决问题,但是java并没有这么个东西,所以就有了下面这段代码逻辑了。
public class StrategyTest {

public static void main(String[] args) {
String result = ObtainStrategyInfo.getInstance().getStrategyInfo("策略一");
System.out.println(result);
}
}

/* (单例模式) */
class ObtainStrategyInfo {

private static final ObtainStrategyInfo obtainStrategyInfo = new ObtainStrategyInfo();

public static ObtainStrategyInfo getInstance(){
return obtainStrategyInfo;
}

public String getStrategyInfo(String strategy){
StrategyInfo strategyInfo = new StrategyFactory().getStrategyInfoClass(strategy);
return strategyInfo.getStrategyInfo(strategy);
}
}
这种单例模式在类一加载的时候就将单例对象创建完毕,总是这个对象存在内存中,避免了通过线程同步来生成对象,线程安全的创建方式。

/* 其实最终的if else判断逻辑都在这里了 (工厂模式)*/
class StrategyFactory {
private static Map<String, StrategyInfo> strategyInfoMap = new HashMap<String, StrategyInfo>();

static {
strategyInfoMap.put("策略一", new Strategy1());
strategyInfoMap.put("策略二", new Strategy2());
}

public StrategyInfo getStrategyInfoClass(String strategy){
StrategyInfo strategyInfo = null;
for(String key : strategyInfoMap.keySet()){
if(strategy.equals(key)) {
strategyInfo = strategyInfoMap.get(key);
}
}
return strategyInfo;
}
}

/* (策略模式) */
interface StrategyInfo {
String getStrategyInfo(String strategy);
}

class Strategy1 implements StrategyInfo {

public String getStrategyInfo(String strategy) {
return strategy;
}
}

class Strategy2 implements StrategyInfo {

public String getStrategyInfo(String strategy) {
return strategy;
}
}

如果需要扩展策略三,是不是只要添加自己的逻辑代码就行了呢?保证对修改关闭?答案是肯定的。可以如下方式来扩展策略三:
/* 在StrategyFactory中注入策略三的对应关系 */
strategyInfoMap.put("策略三", new Strategy3());

/* 然后定义策略三 */
class Strategy3 implements StrategyInfo {

public String getStrategyInfo(String strategy) {
return strategy;
}
}

这样可非常方便的扩展策略四、策略五。
本回答被网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 3条折叠回答
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式