Strategy pattern of java design pattern

strategy mode

The definition of the strategy pattern is: define a series of algorithms, encapsulate them one by one, and make them interchangeable, so that the algorithm can be changed independently of the customers using it.

The design principle is: extract the part of a class that often changes or may change frequently in the future as an interface, and then include an instance of this interface in the using class, so that the object using the class can call the class that implements this interface at will behavior.

There are the following roles in strategy mode:

Environment role (Context): The reference and use of the policy role is implemented in this role.

Abstract strategy role: This role is usually implemented by an abstract class or interface, which defines the behavior of the specific strategy role.

Specific Policy Role: This role encapsulates different algorithms that implement different functions.

The demo code is as follows:

abstract strategy class

public interface Strategy {
    /**
     * Strategy method
     */
    void strategyMethod();
}

Specific role class A

public class ConcreteStrategyA implements Strategy{

    @Override
    public  void strategyMethod() {
         // specific behavior 
    }
}

Concrete role class B

public class ConcreteStrategyB implements Strategy {
    @Override
    public  void strategyMethod() {
         // specific behavior 
    }
}

Environment role class

public class Context {
    /**
     * Holds a specific policy object
     */
    private Strategy strategy;

    /**
     * Constructor, pass in a specific policy object
     * @param strategy The specific strategy object
      */ 
    public Context(Strategy strategy)
    {
        this.strategy = strategy;
    }

    /**
     * Methods of using policies provided externally
     */
    public void contextMethod()
    {
        // The specific strategy object is usually transferred to perform algorithm operation 
        strategy.strategyMethod();
    }
}

Specific Scenario Example of Strategy Pattern

The enterprise service system of a Saas company will determine the preferential strategy according to the customer's purchase time during sales, which is divided into ordinary customers (no preferential policy), large customers (22% off), and strategic customers (5% off). Ordinary customers refer to one-time rental services for one to three years, large customers refer to one-time use services for three to five years, and strategic customers refer to one-time use services for more than five years. Because each customer price algorithm is different, the strategy pattern can be used in this scenario.

Define an interface for calculating price action

public interface SalePrice {
    /**
     * Return different prices based on original price
     * @param originalPrice original price
     * @return
     */
    BigDecimal salePrice(BigDecimal originalPrice);
}

Then define the specific calculation price class (strategy class) of the third customer

public class OriginalCustomer implements SalePrice {
    /**
     * Ordinary customers return the original price directly
     * @param originalPrice original price
     * @return the calculated price
      */
    @Override
    public BigDecimal salePrice(BigDecimal originalPrice) {

        return originalPrice.multiply(BigDecimal.valueOf(1));
    }
}

 

public class LargeCustomer implements SalePrice {
    /**
     * 22% discount for big customers
     * @param originalPrice original price
     * @return the calculated price
      */
    @Override
    public BigDecimal salePrice(BigDecimal originalPrice) {

        return originalPrice.multiply(BigDecimal.valueOf(0.98));
    }
}
public class StrategicCustomer implements SalePrice {
    /**
     * Strategic customers directly return a 5% discount
     * @param originalPrice original price
     * @return the calculated price
      */
    @Override
    public BigDecimal salePrice(BigDecimal originalPrice) {
        return originalPrice.multiply(BigDecimal.valueOf(0.95));
    }
}

The customer class needs to determine which method to call to calculate the price.

public class Customer {

    private  int years;
     /** The initial price of renting the service for one year */ 
    private BigDecimal originalPrice = BigDecimal.valueOf(50000 );
     /** The final price paid by the customer* */ 
    private BigDecimal payForPrice = BigDecimal.ZERO;
     /** Every The initial price of each customer is the original price */ 
    private SalePrice salePrice = new OriginalCustomer();

    /**
     * Calculate the preferential price every year according to the length of the customer's purchase (unit: year)
     * @param years
     */
    public void buy(int years)
    {
        this.years = years;
        payForPrice = originalPrice.multiply(BigDecimal.valueOf(years));
         // Strategic customer price greater than 5 years 
        if (years >= 5 ){
            salePrice = new StrategicCustomer();
        } else  if (years >= 3) // 3 to 5 years discounted price for large customers 
        {
            salePrice = new LargeCustomer();
        } else  if (years >= 1) // Ordinary user price for 1 to 3 years 
        {
            salePrice = new OriginalCustomer();
        }
    }

    /**
     * Calculate the price the customer ends up paying
     * @return
     */
    public BigDecimal payPrice(){
        return salePrice.salePrice(payForPrice);
    }

}

The client calls the class to automatically calculate the payment price

**
 * Client call class
  */
@ Slf4j
public  class Customer {

    public static void main(String[] args){
        Customer customer = new Customer();

        customer.buy(1);
        log.info( "Customers need to pay: {}" ,customer.payPrice());

        customer.buy(3);
        log.info( "Customers need to pay: {}" ,customer.payPrice());

        customer.buy(6);
        log.info( "Customers need to pay: {}" ,customer.payPrice());

    }
}

Output result:

Customer Payable: 50000 
Customer Payable: 147000.00 
Customer Payable: 285000.00

According to the output results, it can be seen that the prices charged for services purchased at different times are different. In this way, customers can directly purchase the services according to the time they need without relying on specific charging methods.

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325414406&siteId=291194637