Requirements:

Calculation: pay 100 yuan, the actual amount of payment wechat 100 minus 20 alipay 100 minus 10 fast

Common implementation

/ * * *@paramPayType Payment mode */
public static void getPayMoney(String payType) {
        int money = 100;
        if (payType.equals("WX")) {
            money = money - 20;
        } else if (payType.equals("ZFB")) {
            money = money - 10;
        }
        System.out.println(money);
    }
public static void main(String[] args) {
	   getPayMoney("WX");
	   getPayMoney("ZFB");
	}
Copy the code

Strategy mode, the principle is to rely on polymorphism instead of if

Composition:

Policies (typically interfaces or abstract classes)

Policy implementation (typically implementation classes)

A policy context (typically a class that contains a private variable of type policy. There is a constructor with a parameter that contains the policy, and the purpose is to assign a value to the policy. There should also be a public method to enforce specific policies.)

Implementation approach

1. Create alipay and wechat payment method classes (known as concrete implementation of policies), both of which have methods to calculate the real payment amount

2. Pull up and think about what the two classes have in common. A calculation interface in which calculation methods are defined (interfaces or abstract classes are called policies)

3. The two classes created in step 1 implement the interfaces of step 2

// wechat 100 minus 20 (strategy implementation)
class WXPay implements RealMoney {
    @Override
    public void getPayMoney(a) {
        System.out.println(100 - 20); }}// Alipay 100 minus 10 fast (specific implementation of strategy)
 class ZFBPay implements RealMoney {
    @Override
    public void getPayMoney(a) {
        System.out.println(100 - 10); }}// Define interfaces (interfaces or abstract classes are called policies)
public interface RealMoney {
    /** * Calculate the payment of 100 yuan, the actual amount paid */
    void getPayMoney(a);
}
Copy the code

4. The first three parts expose and leak interfaces, so we use interfaces to call methods

5. Create a policy context

51. Create the class

Class 5.2 has a member variable of type interface

5.3 Externally assign values to member variables using constructors

5.4 Providing Methods externally: Invoke specific methods using member variables

// Policy context
public class Context {
    / / interface
    private RealMoney realMoney;

    // Assign values to member variables using constructors
    public Context(RealMoney realMoney) {
        this.realMoney = realMoney;
    }
    // The method provided externally
    public void execute(a) {
        // Execute a method that implements a classrealMoney.getPayMoney(); }}Copy the code

6. How to use it

public class test{
    public static void main(String[] args) {
        getPayMoney("WX");
    }
    public static void getPayMoney(String payType) {
        if (payType.equals("WX")) {
            Context context = new Context(new ZFBPay());
            context.execute();
        } else if (payType.equals("ZFB")) {
            Context context = new Context(newWXPay()); context.execute(); }}}Copy the code

7. Wrapped for half a day, that’s it? If/else is still on! Further down the list is the 8.JDK’s policy pattern application ThreadPoolExecutor

The context from ThreadPoolExecutor is what is called the policy pattern


    /** * Handler called when saturated or shutdown in execute. */
    private volatile RejectedExecutionHandler handler;

	public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        //....
        this.handler = handler;
    }

    /** * Invokes the rejected execution handler for the given command. * Package-protected for use by ScheduledThreadPoolExecutor. */
    final void reject(Runnable command) {
        handler.rejectedExecution(command, this);
    }
Copy the code

RejectedExecutionHandler (RejectedExecutionHandler), which represents the rejection policy (there are four implementations: 1) throw the exception, 2) use the caller’s thread to handle the exception, 3) discard the task, and 4) discard the oldest task.

In fact, this is the embodiment of the strategic pattern.

9. That is, not all four rejection strategies may be used in a project, but the Java programmer chooses one.

10. What if he doesn’t use strategic mode? That is, we pass parameters 1, 2, 3, 4, and he uses the rejection policy according to the parameters! This gives ThreadPoolExecutor an if

11. The original strategy mode is polymorphism! Java did it for us!

12. Ok, what if I also want to remove the “if” in step 6? Map is a good thing, get v by key, if our interface has 1000 implementation classes, put < class name, class instance > in map, then we can get the class instance by class name, instead of if thousands of times

13: development: Get (index) = list.get(index) = list.get(index) = list.get(index) = list.get(index) If there are more than eight chains it is a red-black tree lookup

14: Creates a static map. Select ConcurrentHashMap because it is a static map. Avoid thread safety issues

public class test{
    // Define a map. Static variables usually need to be capitalized and meaningful for ease of using map
    private static Map<String,? super RealMoney> map = new ConcurrentHashMap<>();
    // In the static code block, put the object new into the map
    static {
        map.put("WX".new WXPay());
        map.put("ZFB".new ZFBPay());
    }
    // Remove if
    public static void getPayMoney(String payType) {
        Context context = new Context((RealMoney) map.get(payType));
        context.execute();
    }

    public static void main(String[] args) {
        getPayMoney("WX"); }}Copy the code

15. Is this idea a design pattern? Look at the introduction of the simple Factory pattern. It turns out that this is the simple Factory pattern: belongs to the creation pattern also known as the static factory method pattern, which belongs to the class creation pattern. In the simple factory pattern, you can return instances of different classes depending on the parameters. The simple factory pattern specifically defines a class that is responsible for creating instances of other classes, which usually have a common parent class.

16. Consider: adding a payment method later would require rewriting a class that implements the policy interface and adding it to the map.

17. How do I not need to change the map every time? So we can use annotations. Custom annotations, annotations can be annotated on the class, any annotated class will be put into the map, so you don’t have to change the map every time

18. How to use the Spring framework? See the blog address below

From blog address

Novice tutorial

Any design model is a double-edged sword Rookie tutorial design mode is good, are examples of Java code