instructions

When we shopping online payment and settlement, the app will prompt the way we use to pay, we will choose a different way from different places buckles money, this is the application of the strategy pattern, according to the different choose to use different strategies to deal with the same problem Of course, the strategy pattern encoding method has a lot of, The most commonly used is if-else and switch conditional branching judgment. If there are too many policies, there will be a lot of IF-else, and the code is not beautiful. Therefore, using factory mode to optimize the policy mode can solve these problems well

Policy mode general steps

  1. Extract the public interface for all policies
  2. Different policies implement a unified public interface
  3. Choose different strategies to solve problems





Strategy mode scenario deduction

First of all, all payment methods realize the class Pay interface, under which there is only one method, Pay

/** * payment interface */
public interface Pay {
    void pay(int money);
}
Copy the code

With this interface, major manufacturers will implement this interface to make their own payment software, such as AliPay, JDPay, ApplePay and so on

public class AliPay implements Pay{
    @Override
    public void pay(int money) {
        System.out.println("Paid with Alipay" + money + "Yuan"); }}public class JDPay implements Pay{
    @Override
    public void pay(int money) {
        System.out.println("Paid with JDPay" + money + "Yuan"); }}public class ApplePay implements Pay{
    @Override
    public void pay(int money) {
        System.out.println("Paid with ApplyPay." + money + "Yuan"); }}Copy the code

With these payment software, the shopping platform will introduce the interface provided by these payment software to realize multi-software payment

/** * online shopping app */
public class ShoppingApp {

    /** * Select payment method */
    public Pay selectPay(String payName){
        if ("aliPay".equals(payName)){
            return new AliPay();
        }else if ("JDPay".equals(payName)){
            return new JDPay();
        }else if ("applePay".equals(payName)){
            return new ApplePay();
        }else {
            return newAliPay(); }}}Copy the code

Finally, we write a main function to simulate the online shopping scenario

public class Main {
    public static void main(String[] args) {
        ShoppingApp app = new ShoppingApp();
        Pay pay = app.selectPay("aliPay");
        pay.pay(100); }}Copy the code

View the console output













Use factory pattern optimization

If there are only a few policies, you can use this method. Once there are many policies, there will be a lot of if-else, the code is very ugly, and every policy is new, so the policy reuse is not high. Now let’s refactor the ShoppingApp, as shown below

/** * online shopping app */
public class ShoppingApp {

    private static Map<String, Pay> payMap = new HashMap<>();

    static{
        payMap.put("aliPay".new AliPay());
        payMap.put("JDPay".new JDPay());
        payMap.put("applePay".new ApplePay());
    }


    /** * Select payment method */
    public Pay selectPay(String payName){
        Pay pay = payMap.get(payName);
        return Optional.ofNullable(pay).orElse(newAliPay()); }}Copy the code


Let’s test again and see the console result, same result









The last

Adding vendor-implemented support policies to the Map in this hard-coded way does solve the redundant if-else problem, but the code is not scalable because you can only use policies that are already in the Map, and adding new policies requires code modifications that do not comply with the open and close principle. Therefore, you can continue to optimize, create a new method to put the new policy into the map, or define the fully qualified name of the policy class in the configuration file, and use reflection to create the policy class and add it to the map