[Java Language] Ja.2.3--Talking about the strategy mode of design mode (3)

1. Overview of Strategic Patterns

First, give an official-sounding definition: a policy pattern abstracts the variable parts from the program into an algorithm interface, under which a series of algorithm implementations are encapsulated.

To illustrate this, we will find that e-commerce platforms generally offer a variety of payment options when shopping online. Users only need to select one of them to make payment.

You can find that the payment algorithm in the above example is an abstract algorithm interface, which encapsulates the implementation of various payment algorithms, such as ICB Payment, Alipay Payment...Wait.In this way, when a new payment method needs to be added, only a new algorithm implementation needs to be provided under the interface, and the client can be independent of this change.You can see that policy patterns have flexible support for new needs.

2. Explain the implementation of the strategy pattern with an example

We illustrate the strategy model with an example of user online purchase payments at the beginning of the article.Start with the following basic code, which includes an abstract customer base class, Consumer.java, and two customer classes.

Consumer.java:

package com.bebdong.Strategy_pattern;

/**
 * @author Administrator
 * User's abstract class
 */
public abstract class Consumer {

    public void login(){
        System.out.println("User Login");
    }

    public void buy(){
        System.out.println("User Purchase");
    }

    public abstract void display();
}

ConsumerA.java:

package com.bebdong.Strategy_pattern;

public class ConsumerA extends Consumer {

    public ConsumerA() {
        super();
    }

    @Override
    public void display() {
        System.out.println("I'm a customer type A......");
    }

}

ConsumerB.java:

package com.bebdong.Strategy_pattern;

public class ConsumerB extends Consumer {

    public ConsumerB() {
        super();
    }

    @Override
    public void display() {
        System.out.println("I'm a customer type B......");

    }

}

OK, with that foundation in mind, let's discuss how to implement such an action as payment:

  1. Inheritance: Like the buy() and login() methods, implement a pay() in an abstract base class to implement payments.Although such a simple (cu) single (bao), it also has a considerable disadvantage: it is not flexible enough.Because different customers prefer different payment methods.
  2. Abstract method (polymorphism): Like dispaly() method, add an abstract method pay() to the abstract base class to force subclasses to implement it.In this way, it seems to solve the problem of the first scenario, but when we think about it carefully, we can see that the flexibility of future demand is not high, a user may have several payment methods, and it is not conducive to code maintenance.Imagine that if one day we need to change the name of this payment method (which may be inappropriate, just an example), then the code for each customer type needs to be modified.
  3. Combination.

After the above analysis, we say that inheritance is a useful tool for code reuse in object-oriented programming, but sometimes it has unavoidable drawbacks.In Effective Java, there is one sentence: Favor composition over inheritance. It roughly means that combination is better than inheritance.So what is a combination?

Adding a private domain to a class, referencing another instance of an existing class, and invoking the method of referencing an instance to get something, a design called composition (composition).

Using the idea of combinatorial and strategic models, we have come up with the following scenarios: add a PayWay payment interface, and then add different payment method classes to implement such an interface.

PayWay.java (abstracting commonalities as interfaces)

package com.bebdong.Strategy_pattern;

public interface PayWay {

    public void performPay();
}

Consumer.java: Modify accordingly (object classes have policy interfaces)

package com.bebdong.Strategy_pattern;

/**
 * @author Administrator
 * User's abstract class
 */
public abstract class Consumer {

    public void login(){
        System.out.println("User Login");
    }

    public void buy(){
        System.out.println("User Purchase");
    }

    public abstract void display();

    /*The following section is the new code*/
    private PayWay payWay;
    public void setPayWay(PayWay payWay){
        this.payWay=payWay;
    }

    public void pay(){
        payWay.performPay();
    }
}

Here we encapsulate two payment methods for specific instructions: (Add a policy implementation class)

AliPay.java:

package com.bebdong.Strategy_pattern;

public class AliPay implements PayWay {

    @Override
    public void performPay() {
        System.out.println("Pay with Alipay");
    }

}

ICBCPay.java:

package com.bebdong.Strategy_pattern;

public class ICBCPay implements PayWay {

    @Override
    public void performPay() {
        System.out.println("Industrial Bank Payment");

    }

}

Suppose user type A uses Alipay payments, and user type B uses ICBC payments (injecting different policies into different objects)
Here we use ConsumerTest.java to simulate this process:

package com.bebdong.Strategy_pattern;

public class ConsumerTest {

    public static void main(String[] args) {
        System.out.println("====Simulation Start====");

        Consumer consumerA=new ConsumerA();
        Consumer consumerB=new ConsumerB();
        consumerA.setPayWay(new AliPay());
        consumerB.setPayWay(new ICBCPay());

        System.out.println(">>>>Here is the user A<<<<");
        consumerA.display();
        consumerA.login();
        consumerA.buy();
        consumerA.pay();

        System.out.println(">>>>Here is the user B<<<<");
        consumerB.display();
        consumerB.login();
        consumerB.buy();
        consumerB.pay();

        System.out.println("====End of simulation====");

    }

}

Run to get the following results:

This way, when a new payment method needs to be added, you only need to inherit the PayWay interface and provide a specific implementation.All customers can choose to pay in this way.

3. Summary

From the example above, we can summarize the design principles of the strategy pattern:

  • 1. Abstract the unchanged part of the application as an interface and turn it into a partial implementation;
  • 2. Interface-oriented programming, not implementation-oriented programming.Interfaces define the implementation framework, and then diversity is achieved through polymorphism.
  • 3. Combinatorial Priority Inheritance.

Key Points for Implementing the Strategic Mode <<<<<<<<<<<<<<<<<<>

  • 1. Dispose of policy interfaces through analysis;
  • 2. Provide implementation classes for interfaces;
  • 3. The object "owns" a Strategy through which to implement specific behaviors;

  • 4. Select/assemble the correct Strategy implementation in the client program.

The Advantages of the Strategic Mode <<<<<<<<<<<<<<<<<<>

  • 1. Strategic patterns are often inseparable from composition, and the architecture is flexible.
  • 2. Be flexible and can better cope with changes in demand (on-off);
  • 3. Better code reuse
  • 4. Quite a few conditional statements have been eliminated (there is no need to decide which behavior to perform) and are easy to maintain.

Defects of the Strategic Mode <<<<<<<<<<<<<<<<<<<<<>

  • 1. You can see that you need to inject a policy (point 4) into each class (object), so the client needs to know the implementation details of the policy.
  • 2. Over time, the number of policy implementation classes will increase significantly.

Scenarios for using the strategy mode <<<<<<<<<<<<<<<<<>>>>>>>>>>>>> Strategy mode

  1. Many related classes are merely behavioral differences, abstracting common differences as policy interfaces;
  2. Select different algorithm variants at runtime.If different payment algorithms are used, only one payment algorithm will run at runtime.
  3. The program contains equivalent conditional statements if...else....

Keywords: Java Programming

Added by cabaz777 on Fri, 12 Jul 2019 19:55:07 +0300