A day of humble test ------ strategy mode + factory mode to replace if else

Do you often encounter too many if else in the coding process? Although the writing logic will be very clear, once the conditions increase, the code will appear bloated, there are many branches, and it is difficult to maintain. In this case, if else is definitely not recommended, even if it is maintained later in order to speed up the progress at the beginning, it will reduce the efficiency.

Let's first look at this pile of Xiang like if else branches

public void pay(String type,String order) {

        if (type.equals("wechatPay")) {
          wechatPay(order);
        } else if (type.equals("ailiPay")) {
          ailiPay(order);
        } else if (type.equals("googlePay")) {
          googlePay(order);
        } else {
          normalPay(order)
        }
    }

If you add a new payment method one day, you need to add an if else again. Over time, this code will become the annoying "shit mountain" in the legend.
If you don't want to maintain this code, you need to introduce a policy pattern to eliminate infinite if else logic

Strategy mode

A series of algorithms are defined, and each algorithm is encapsulated, so that each algorithm can replace each other, so that the algorithm itself and the client using the algorithm are separated and independent of each other.

An opening and closing principle based on strategy mode

Opening and closing principle:
  Open for extension. This means that the behavior of the module is extensible. When the requirements of the application change, we can extend the module to meet those changed new behaviors. In other words, we can change the function of the module.   
  Closed for modification. When extending the module behavior, it is not necessary to change the source code or binary code of the module.

Refactoring using policy patterns

First define an interface

public interface payStrategy{
    int pay(String order)
}

Then create the above four policy implementation classes to implement the interfaces

public class WechatPay implements payStrategy{

    public int pay (String orderNo)  {
     ....
    }
public class ailiPay implements payStrategy{

    public int pay (String orderNo)  {
     ....
    }
public class googlePay implements payStrategy{

    public int pay (String orderNo)  {
     ....
    }
public class normalPay implements payStrategy{

    public int pay (String orderNo)  {
     ....
    }

You may still have doubts here. I don't know when to call that method? It still needs if or switch to judge
Break?

Yes, the transformation has not been completed at this stage. At this time, we need to introduce the channel code and dynamically obtain the specific implementation class through our self-defined channel code, so that we can realize that we do not need if else judgment. How to get the implementation class through the channel code?

Factory mode

public class PayFactory {
    enum PayType {
        WECHATPAY("wechatPay", "Wechat payment"),
        ALIPAY("aliPay", "Ali payment"),
        GOOGOLEPAY("googlepay", "Google pay");
        ONRMALPAY("normalPay", "General payment");
        // Code corresponding to the scene
        private String code;
        // Business scenario description
        private String desc;
        ShareType(String code, String desc) {
            this.code = code;
            this.desc = desc;
        }
        public String getCode() {
            return code;
        }
        // Omit the get set method
    }

    // Define policy map cache
    private static final Map<String, PayStrategy> payStrategies = new HashMap<>();

    static {
        payStrategies.put("wechatPay", new WechatPay ());
        payStrategies.put("aliPay", new ailiPay ());
        payStrategies.put("googlepay", new googlePay ());
        payStrategies.put("normalPay", new normalPay ());
    }

    // Gets the specified policy
    public static MockPayStrategy getPayStrategy(String type) {
        if (type == null || type.isEmpty()) {
            throw new IllegalArgumentException("type should not be empty.");
        }
        return payStrategies.get(type);
    }


}

At this point, the transformation is basically completed. Is the code refreshing after eliminating the stacking of if else

summary

Assuming that a new payment method needs to be accessed and the policy mode + factory mode is adopted, there is no need to use else if to judge. Now you only need to define a new enumeration object in the enumeration, and then add a policy implementation class to implement the logic of the corresponding method, which can be easily extended. The principle of opening and closing is also realized.

Keywords: Java

Added by Spreegem on Tue, 12 Oct 2021 21:29:27 +0300