如何用卫语句、策略模式、状态模式重构if-else语句

Deadly 提交于 2019-11-28 06:02:24

《java开发手册》中:

况且日常开发时遇到一推的if-else着实让人头疼!

so,现在开始改造

一、卫语句

卫语句就是把复杂的条件表达式拆分成多个条件表达式,即代码逻辑先考虑失败、异常、中断、退出等直接返回的情况,以方法多个出口的方式,解决代码中判断分支嵌套的问题,这是逆向思维的体现

比如:

if (type == 0) {
     code...
}else if (type == 1) {
     code...
} else if (type == 2) {
     code...
} else {
    otherCode...
}  

可以改造为:

if (type == 0) {
   code...
   return;
}
if (type == 1) {
   code...
   return;
}
if (type == 2) {
    code...
    return;
}
otherCode....

二、策略模式 

如果不了解策略模式,可以去看下菜鸟教程中的例子,简单明了,地址:https://www.runoob.com/design-pattern/strategy-pattern.html

现在有个需求,根据用户的类型来展示不同的内容,我们将其具体化为一段代码:

if ("新客户".equals(userType)) {
  showNewContent...;
}else if("VIP客户".equals(userType)){
  showVIPContent...;
}else if ("白金客户".equals(userType)) {
  showPlatinaContent...;
}else if ("黑卡用户".equals(userType)){
  showBlackCardContent...;
}else if ("回归用户".equals(userType)){
  showComeBackContent...;
}else {
  showOtherContent...;
}

  这样看是看不出来有何不妥的,但是想想,要推荐的内容何止这么点代码,如果不管不顾,就这么写,到时候写完代码回过头来,自己都得看老半天才能看懂,何论后期维护的人呢,而且要是后期又添加了一种新的用户类型,那是不是又要写一个else-if插在中间,然后又增量添加一推代码,这样岂不是太麻烦了?,反正强迫症肯定是受不了的

策略模式改造:

1.定义一个策略接口

public interface ShowStrategy{
    void showContentByUserType();
}

2.定义多个具体的策略实现

public class ShowNewContentStrategy implements ShowStrategy {
    @Override
    public void showContentByUserType() {
        System.out.println("展示新用户内容");
    }
}
public class ShowVIPContentStrategy implements ShowStrategy {
    @Override
    public void showContentByUserType() {
        System.out.println("展示VIP用户内容");
    }
}
public class ShowPlatinaContentStrategy implements ShowStrategy {
    @Override
    public void showContentByUserType() {
        System.out.println("展示白金用户内容");
    }
}    
public class ShowBlackCardContentStrategy implements ShowStrategy {
    @Override
    public void showContentByUserType() {
        System.out.println("展示黑卡用户内容");
    }
}
public class ShowComeBackContentStrategy implements ShowStrategy {
    @Override
    public void showContentByUserType() {
        System.out.println("展示回归用户内容");
    }
}

3.定义一个策略使用的client

public class ShowStrategyClient {
    //持有一个策略接口引用
    private ShowStrategy showStrategy;
    //注入
    public ShowStrategyClient(ShowStrategy showStrategy) {
        this.showStrategy = showStrategy;
    }
    //策略client的方法
    public void clientMethod(){
        showStrategy.showContentByUserType();
    }
}

4.外部使用

回到我们的需求,用写好的策略模式重构

public void test() {
  //1.创建新用户的内容展示策略
  ShowStrategy newContentStrategy = new ShowNewContentStrategy();
  //2.创建策略客户端,注入新用户策略实现
  ShowStrategyClient showStrategyClient = new ShowStrategyClient(newContentStrategy);
  showStrategyClient.clientMethod();
}  

三、状态模式

继续引用我们在“二、策略模式”中的例子

状态模式改造:

1.定义一个状态行为接口

interface UserState {
    void showNewContent(ShowStateClient client);
    void showVIPContent(ShowStateClient client);
    void showPlatinaContent(ShowStateClient client);
    void showBlackCardContent(ShowStateClient client);
    void showComeBackContent(ShowStateClient client);
}

2.定义多个具体的状态实现

public class ShowNewContentState implements UserState {
    @Override
    public void showNewContent(ShowStateClient client) {
        System.out.println("展示新用户内容");
    }
    @Override
    public void showVIPContent(ShowStateClient client) {
        System.out.println("用户状态错误");
    }
    @Override
    public void showPlatinaContent(ShowStateClient client) {
        System.out.println("用户状态错误");
    }
    @Override
    public void showBlackCardContent(ShowStateClient client) {
        System.out.println("用户状态错误");
    }
    @Override
    public void showComeBackContent(ShowStateClient client) {
        System.out.println("用户状态错误");
    }
}
public class ShowVIPContentState implements UserState {
    @Override
    public void showNewContent(ShowStateClient client) {
        System.out.println("用户状态错误");
    }
    @Override
    public void showVIPContent(ShowStateClient client) {
        System.out.println("展示VIP用户内容");
    }
    @Override
    public void showPlatinaContent(ShowStateClient client) {
        System.out.println("用户状态错误");
    }
    @Override
    public void showBlackCardContent(ShowStateClient client) {
        System.out.println("用户状态错误");
    }
    @Override
    public void showComeBackContent(ShowStateClient client) {
        System.out.println("用户状态错误");
    }
}
public class ShowPlatinaContentState implements UserState {
    @Override
    public void showNewContent(ShowStateClient client) {
        System.out.println("用户状态错误");
    }
    @Override
    public void showVIPContent(ShowStateClient client) {
        System.out.println("用户状态错误");
    }
    @Override
    public void showPlatinaContent(ShowStateClient client) {
        System.out.println("展示白金用户内容");
    }
    @Override
    public void showBlackCardContent(ShowStateClient client) {
        System.out.println("用户状态错误");
    }
    @Override
    public void showComeBackContent(ShowStateClient client) {
        System.out.println("用户状态错误");
    }
}
public class ShowBlackCardContentState implements UserState {
    @Override
    public void showNewContent(ShowStateClient client) {
        System.out.println("用户状态错误");
    }
    @Override
    public void showVIPContent(ShowStateClient client) {
        System.out.println("用户状态错误");
    }
    @Override
    public void showPlatinaContent(ShowStateClient client) {
        System.out.println("用户状态错误");
    }
    @Override
    public void showBlackCardContent(ShowStateClient client) {
        System.out.println("展示黑卡用户内容");
    }
    @Override
    public void showComeBackContent(ShowStateClient client) {
        System.out.println("用户状态错误");
    }
}
public class ShowComeBackContentState implements UserState {
    @Override
    public void showNewContent(ShowStateClient client) {
        System.out.println("用户状态错误");
    }
    @Override
    public void showVIPContent(ShowStateClient client) {
        System.out.println("用户状态错误");
    }
    @Override
    public void showPlatinaContent(ShowStateClient client) {
        System.out.println("用户状态错误");
    }
    @Override
    public void showBlackCardContent(ShowStateClient client) {
        System.out.println("用户状态错误");
    }
    @Override
    public void showComeBackContent(ShowStateClient client) {
        System.out.println("展示回归用户内容");
    }
}

3.定义一个状态使用的client

public class ShowStateClient {    private UserState userState;    public void setUserState(UserState userState){        this.userState = userState;    }    public UserState getUserState(){        return userState;    }    public void showNewContent() {        userState.showNewContent(this);    }    public void showVIPContent() {        userState.showVIPContent(this);    }    public void showPlatinaContent() {        userState.showPlatinaContent(this);    }    public void showBlackCardContent() {        userState.showBlackCardContent(this);    }    public void showComeBackContent() {        userState.showComeBackContent(this);    }}

4.外部使用

public static void main(String[] args) {    ShowStateClient client = new ShowStateClient();    client.setUserState(new ShowNewContentState());    client.showNewContent();    client.showVIPContent();    client.showPlatinaContent();    client.showBlackCardContent();    client.showComeBackContent();}

  

个人觉得状态模式过于臃肿,用处反而没有特别突出,不过也许是我没有遇到合适的场景或者理解有误吧!

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!