Java 23 design patterns -- policy pattern (behavior design pattern)

Keywords: Java Apache Design Pattern Back-end

Strategy mode

brief introduction

The policy pattern is the packaging of the algorithm. It separates the responsibility of using the algorithm from the algorithm itself and delegates it to different objects for management. Policy patterns usually package a series of algorithms into a series of policy classes as subclasses of an abstract policy class. In a word, "prepare a set of algorithms and package each algorithm so that they can be interchanged". The following is a schematic implementation to explain the structure of the policy pattern example.

role

  • Context role: holds a reference to Strategy.

  • Abstract strategy role: This is an abstract role, usually implemented by an interface or abstract class. This role gives the interfaces required for all specific policy classes.

  • Concrete strategy role: encapsulates related algorithms or behaviors.

code

Project structure

Instance scenario

Suppose we want to design a shopping cart system of e-commerce website selling all kinds of books. The simplest case is to multiply the unit price of all goods by the quantity, but the actual situation must be more complicated than this. For example, this website may provide 20% promotion discount for all senior members; Offer 10% promotion discount for intermediate members; There is no discount for junior members.

According to the description, the discount is performed according to one of the following algorithms:

  • Algorithm 1: there is no discount for junior members.

  • Algorithm 2: offer 10% promotion discount to intermediate members.

  • Algorithm 3: offer 20% promotion discount to senior members.

The structure diagram of using policy mode is as follows:

Abstract discount class

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

Discount category

/**
 * Junior member discount
 */
public class PrimaryMemberStrategy implements MemberStrategy {

    @Override
    public double calcPrice(double booksPrice) {
        
        System.out.println("There is no discount for junior members");
        return booksPrice;
    }

}

/**
 * Intermediate member discount
 */
public class IntermediateMemberStrategy implements MemberStrategy {

    @Override
    public double calcPrice(double booksPrice) {

        System.out.println("The discount for intermediate members is 10%");
        return booksPrice * 0.9;
    }

}

/**
 * Premium member discount
 */
public class AdvancedMemberStrategy implements MemberStrategy {

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

Price category

public class Price {
    //Hold a specific policy object
    private MemberStrategy strategy;
    /**
     * Constructor, passing in a specific policy object
     * @param strategy    Specific policy objects
     */
    public Price(MemberStrategy strategy){
        this.strategy = strategy;
    }

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

Test class

public class ApiTest {

    @Test
    public void testCommand(){
        //Select and create the policy object you want to use
        MemberStrategy strategy = new AdvancedMemberStrategy();
        //Create environment
        Price price = new Price(strategy);
        //Calculate price
        double quote = price.quote(300);
        System.out.println("The final price of the book is:" + quote);
    }

}

advantage

  1. The policy pattern provides a way to manage related algorithm families. The hierarchy of policy classes defines a family of algorithms or behaviors. Proper use of inheritance can move public code to the parent class, so as to avoid code duplication.
  2. Using the policy pattern avoids the use of multiple conditional (if else) statements. Multiple conditional statements are not easy to maintain. They mix the logic of which algorithm or behavior to adopt with the logic of algorithm or behavior. They are all listed in a multiple conditional statement, which is primitive and backward than the method of inheritance.

shortcoming

  1. The client must know all policy classes and decide which policy class 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 applies only when the client knows the algorithm or behavior.
  2. Because the policy pattern encapsulates each specific policy implementation into a class, if there are many alternative policies, the number of objects will be considerable.

Posted by nysmenu on Wed, 24 Nov 2021 19:32:33 -0800