Behavioral Design Patterns-Strategic Patterns

Keywords: Android Attribute

1. Concept of State Patterns

1.1 Introduction

Usually, if there are multiple solutions to a problem, the simplest way is to use if-else or switch-case to choose different solutions according to different scenarios, but such coupling is too high, the code is bloated, and it is difficult to maintain.
If these algorithms or strategies are abstracted to provide a unified interface, different algorithms or strategies have different implementation classes, so that different implementation objects can be injected into the program client to realize the dynamic replacement of algorithms or strategies, the scalability and maintainability of this model will be higher. That is the strategy mode of this chapter.

1.2 Definition

The policy pattern defines a series of algorithms and encapsulates each one so that they can be replaced with each other. The policy pattern allows the algorithm to change independently of the users who use it.

1.3 Use scenarios

(1) There are many ways to deal with the same type of problem, only when the specific behavior is different.
(2) When multiple operations of the same type need to be encapsulated safely.
(3) When there are multiple subclasses of the same abstract class, and if-else or switch-case are needed to select specific subclasses.

1.4 Key Points

The focus of policy mode is not how to implement algorithms, but how to organize and call these algorithms, so that the program structure is more flexible and has better maintainability and expansibility.

2. Universal UML Class Diagram of Policy Patterns

(1) Context role: Hold a Strategy reference.
(2) Strategy role: This is an abstract role, usually implemented by an interface or abstract class. This role gives all the interfaces required for specific policy classes.
(3) Concrete Strategy roles: wrapping related algorithms or behaviors.

3 General template for policy pattern

(1) abstract strategic roles

public interface Strategy { 
    public void doSomething();
}

(2) Specific strategic roles

public class ConcreteStrategyA implements Strategy {
    public void doSomething() {
        System.out.println("Specific strategies A Operational Rules");
    }
}

public class ConcreteStrategyB implements Strategy {
    public void doSomething() {
        System.out.println("Specific strategies B Operational Rules");
    }
}

(3) Encapsulating roles

public class Context {
    private Strategy strategy = null; // Constructor Setting Specific Strategy
    public Context(Strategy _strategy) {
        this.strategy = _strategy;
    }
    // Policy Approaches after Encapsulation
    public void doAnythinig() {
        this.strategy.doSomething();
    }
}

(4) High-level module

public class Client {
    public static void main(String[] args) { 
        // Declare a specific strategy
        Strategy strategy = new ConcreteStrategy1(); 
        // Declare context objects
        Context context = new Context(strategy); 
        // Execute encapsulated methods
        context.doAnythinig();
    }
}

(5) Summary
The basic strategy model is so simple that you can enjoy it secretly. It adopts the object-oriented inheritance and polymorphism mechanism.

Simple Implementation of 4 Policy Patterns

Demand: For calculating the price of books, there is no discount for junior members, 9 for intermediate members and 8 for senior members. In general, it should be if-else that judges what level of membership he is and calculates the corresponding discount. The following is implemented using the policy pattern.
Know the algorithm;
Algorithm1: No discount for junior members.
Algorithm2: Provide a 10% discount on promotion for intermediate members.
Algorithm3: Provide a 20% discount for senior members.

(1) Abstract discount class

public interface MemberStrategy {
    /**
     * Calculating the Price of Books
     * @param booksPrice Price of books
     * @return Calculate the discounted price
     */
    public double calcPrice(double booksPrice);
}

(2) Junior member discounts

public class PrimaryMemberStrategy implements MemberStrategy {
    @Override
    public double calcPrice(double booksPrice) {
        System.out.println("No discount for junior members");
        return booksPrice;
    }
}

(3) Intermediate member discounts

public class IntermediateMemberStrategy implements MemberStrategy {
    @Override
    public double calcPrice(double booksPrice) {
        System.out.println("10% discount for intermediate members%");
        return booksPrice * 0.9;
    }
}

(4) Senior Membership Discounts

public class AdvancedMemberStrategy implements MemberStrategy{
    @Override
    public double calcPrice(double booksPrice) {
        System.out.println("20% discount for senior members%");
        return booksPrice * 0.8;
    }
}

(5) Price category

public class Price {
    // Holding a specific strategic target
    private MemberStrategy strategy;

    /**
     * Constructor, passing in a specific policy object
     */
    public Price(MemberStrategy strategy) {
        this.strategy = strategy;
    }

    /**
     * Calculating the Price of Books
     * @param booksPrice Price of books
     * @return Calculate the discounted price
     */
    public double quote(double booksPrice) {
        return this.strategy.calcPrice(booksPrice);
    }
}

(6) Client

public class Client {
    public static void main(String[] args) {
        MemberStrategy strategy = new IntermediateMemberStrategy();// Select and create policy objects that need to be used
        Price price = new Price(strategy);// Creating an environment
        double quote = price.quote(300);// Calculate the price
        System.out.println("The final price of the book is:" + quote);
        System.out.println("-----------------------------");
        MemberStrategy strategy2 = new AdvancedMemberStrategy();
        Price price2 = new Price(strategy2);
        double quote2 = price2.quote(300);
        System.out.println("The final price of the book is:" + quote2);
    }
}

(7) Results

5 Policy Patterns in Android Source

(1) Time Interpolator
Linear Interpolator, Accelerate Interpolator, Cycle Interpolator, etc. implement Interpolator. Get the current percentage of time through getInterpolator (float input) to calculate the attribute value of animation.

6. The Difference between Strategic Model and Factory Model

7 Summary

7.1 Advantages

(1) The policy pattern provides a way to manage the family of related algorithms. The hierarchical structure of policy classes defines an algorithm or behavior family. Proper use of inheritance can move common code into the parent class, thus avoiding code duplication.
(2) The use of policy patterns can avoid the use of multiple conditional (if-else) statements. Multiple conditional statements are not easy to maintain, which algorithm will it adopt for subclasses to implement?

7.2 Disadvantage

(1) The client must know all the policy classes and decide which one to use. This means that the client must understand the differences between these algorithms in order to select the appropriate algorithm class in time. In other words, the policy pattern only applies when the client knows the algorithm or behavior.
(2) Since policy patterns encapsulate each specific policy implementation as a class, if there are many alternative strategies, the number of objects will be considerable.

8 Reference Articles and Links

Android Source Code Design Patterns Analysis and Practice

Zen of Design Patterns

Reading Notes of Android Source Design Patterns Analysis and Practice (7)

Posted by mayanktalwar1988 on Fri, 21 Jun 2019 14:06:01 -0700