Multi-layer nested problem optimization of conditional statements, help you write code that does not let colleagues complain

The article was first published on the public account (Moon with Feiyu), and then synchronized to the personal website: xiaoflyfish.cn/

If you like it, I will share more series of articles in the future!

I feel that I have gained something, I hope to help you like it, forward it, thank you, thank you

  • WeChat search: Flying Fish on the Moon, make friends, join the interview exchange group

Reply to 666 in the background of the official account, you can get free e-books

foreword

In the "Alibaba Development Manual", there are suggestions and solutions about multiple if-else branches and nesting, as follows:

insert image description here

So this article introduces several optimization schemes to provide you with some ideas

case

The following is typical code you might encounter in development:

public String getTweetTitle(int type) {
        String result;
        if (type == 0) {
            throw new IllegalArgumentException("参数有误");
        }

        //长贴-->获得长帖标题
        if (isPaperTweet(type)) {
            result = getPaperTweetTitle();
        } else {
            // 视频贴-->获得视频贴标题
            if (isVideoTweet(type)) {
                result = getVideoTitle();
            } else {
                result = getDefaultTitle();
            }
        }
        return result;
    }
复制代码

In this case, how can we replace the multi-branch and branch nesting problems? How to make the code easier to maintain and extend?

You can think about it for yourself...  

insert image description here

Below I provide a few methods

guard statement

The book "Refactoring - Improving the Design of Existing Code" has the following description:

If a condition is extremely rare, it should be checked by itself and returned from the function as soon as the condition is true. Such separate checks are often referred to as "guardian statements".

insert image description here

insert image description here

Using guard statements, we can modify the above example to:

public String getTweetTitle(int type) {
        // 条件检查
        if (type == 0) {
            throw new IllegalArgumentException("参数有误");
        }

        // 长贴-->获得长帖标题
        if (isPaperTweet(type)) {
            return getPaperTweetTitle();
        }

        // 视频贴-->获得视频贴标题
        if (isVideoTweet(type)) {
            return getVideoTitle();
        }

        return getDefaultTitle();
    }
复制代码

Check the condition first, and then convert the if-else logic into the corresponding guard statement format.

enumerate

"Effective Java Chinese Edition" in Article 30: Use enum instead of int constants section has a description: Use enumeration to replace branch statement, although it loses the simplicity, it is safer and more flexible.

By defining an abstract function inside the enumeration, each enumeration constant overrides the function, so that the expected calculation result can be obtained by calling the function after obtaining the enumeration constant according to the enumeration value.

The sample code is as follows:

public enum TweetStrategyEnum {

    PAPER(1) {
        @Override
        double getTitle() {
            return "长贴标题";
        }
    },
    VIDEO_TWEET(2) {
        @Override
        double getTitle() {
            return "视频贴标题";
        }
    },
    DEFAULT_TWEET(3) {
        @Override
        double getTitle() {
            return "短贴标题";
        }
    };

    private final int type;

    TweetStrategyEnum(int type) {
        this.type = type;
    }

    abstract String getTitle();

    public static TweetStrategyEnum valueOf(int type) {
        for (TweetStrategyEnum tweetStrategyEnum : TweetStrategyEnum.values()) {
            if (tweetStrategyEnum.type == type) {
                return tweetStrategyEnum;
            }
        }
        return null;
    }
}
复制代码

When using, obtain the enumeration object according to the enumeration value, and directly call the strategy corresponding to the enumeration constant:

public void getTitle() {
        TweetStrategyEnum tweetStrategyEnum = TweetStrategyEnum.valueOf(1);
        if(tweetStrategyEnum != null){
            System.out.println(tweetStrategyEnum.getTitle());
        }
    }
复制代码

state mode

The Zen of Design Patterns chapter states:

insert image description here

One of the advantages of the state pattern is "clear structure". The state mode embodies the open-closed principle and the single-responsibility principle, and is easy to expand and maintain.

The so-called clear structure is to avoid the use of too many switch-case or if-else statements, avoid the complexity of the program, and improve the maintainability of the program.

The case provided by the book "Zen of Design Patterns" is very similar to the one given in the article. Different behaviors are performed according to the current state. If you are interested, you can look it up.

Also optimize the above case code:

Define a state behavior interface

public interface TweetState {
    String getTitle();
}
复制代码

Define multiple concrete state implementations

public class VideoTweetState implements TweetState{
    @Override
    public String getTitle() {
        return "视频贴";
    }
}

public class PaperTweetState implements TweetState{
    @Override
    public String getTitle() {
        return "长贴标题";
    }
}

public class DefaultTweetState implements TweetState{
    @Override
    public String getTitle() {
        return "短贴标题";
    }
}
复制代码

Define a client for state use

public class Client {

    private TweetState tweetState;

    public TweetState getTweetState() {
        return tweetState;
    }

    public void setTweetState(TweetState tweetState) {
        this.tweetState = tweetState;
    }

    public void getTitle() {
        tweetState.getTitle();
    }
}
复制代码

External use

public static void main(String[] args) {
        Client client = new Client();
        client.setTweetState(new VideoTweetState());
        client.getTitle();
    }
复制代码

Strategy + Factory Pattern

First, we abstract each conditional logic code block into a public interface, we can get the following code:

public interface ITweetService {
    String getTitle();
}
复制代码

According to each logical condition, we define the corresponding strategy implementation class, and the following code can be obtained:

public class PaperTweetServiceImpl implements ITweetService{
    @Override
    public String getTitle() {
        return "长贴标题";
    }
}

public class VideoTweetServiceImpl implements ITweetService{
    @Override
    public String getTitle() {
        return "视频贴标题";
    }
}
复制代码

Next, we define the policy factory class to manage these policy classes, as follows:

public class TweetServicesFactory {

    private static final Map<String, ITweetService> map = new HashMap<>();
    static {
        map.put("paperTweet", new PaperTweetServiceImpl());
        map.put("videoTweet", new VideoTweetServiceImpl());
    }
    public static ITweetService getTweetService(String type) {
        return map.get(type);
    }
}
public static void main(String[] args) {
        ITweetService tweetService = TweetServicesFactory.getITweetService(1);
        tweetService.getTitle();
    }
复制代码

Summarize

This article mainly talks about how to solve the if-else statement expansion and multi-level nesting problems. It can be solved by guard statement, enumeration, state mode, strategy + factory mode, etc. If you have a better solution, you can communicate with me

I hope you can try to use these methods in actual development to write more elegant code.

finally

Feel good, remember to like, forward, share, thank you

WeChat search: Flying Fish on the Moon, make friends, join the interview exchange group

Reply to 666 in the background of the official account, you can get free e-books

Guess you like

Origin juejin.im/post/7079251131020345351