Strategy Pattern of java design pattern (Strategy Pattern)

concept

Strategy Pattern: Define a series of algorithms, encapsulate each algorithm, and make them interchangeable. The strategy pattern lets the algorithm vary independently of the clients that use it, also known as the policy pattern (Policy).

use

Combined with the concept of strategy mode, let's find a practical scene to understand.

Suppose we are a newly opened bookstore. In order to attract customers, we launch membership services. We divide the members in the store into three types, namely junior members, intermediate members and senior members. We offer different discounts for different levels of members. We do not discount books for junior members, 10% for intermediate members, and 20% for senior members.

We hope that when the user pays, he only needs to swipe the barcode of the book, and the member swipe his membership card again, so that the staff at the cash register can directly know how much should be charged to the customer.

In the case of not using patterns, we can use statements in the settlement method if/elseto distinguish different members to calculate the price.

But what if we want to change the junior member discount to 12% off one day? What if I want to launch a super membership one day? What if one day I want to limit the number of books that can be discounted for intermediate members?

Using if\elsethe designed system, all the algorithms are written together, as long as there is a change, I have to modify the entire class. We all know that as long as the code is modified, it is possible to introduce problems. To avoid this problem, we can use strategy pattern. . .

For the cash register system, when calculating receivables, a customer can only be one of the primary, intermediate, and senior members. Different affiliates use different algorithms to calculate prices. The cash register system does not actually care about the relationship between specific membership types and discounts. You also don't want any changes between memberships and discounts to affect the checkout system.

Before introducing the specific implementation of the strategy pattern, let's consolidate a few object-oriented design principles: 封装变化, 多用组合,少用继承, 针对接口编程,不针对实现编程. Think about how it can be applied to the strategy pattern, and what are the benefits.

Method to realize

The strategy pattern includes the following roles:

Context: environment class

Strategy: abstract strategy class

ConcreteStrategy: concrete strategy class

[strategy][4]

We use the strategy pattern to realize the cash register system of the bookstore. We can abstract members into a strategy class, and different member types are specific strategy classes. The algorithm for calculating prices is implemented in different strategy classes. Then integrate the members into the cash register by means of combination.

First define an interface, this interface is an abstract strategy class, this interface defines the method of calculating the price, and the specific implementation method is defined by the specific strategy class.

/**
 * Created by hollis on 16/9/19. 会员接口
 */
public interface Member {

    /**
     * 计算应付价格
     * @param bookPrice 书籍原价(针对金额,建议使用BigDecimal,double会损失精度)
     * @return 应付金额
     */
    public double calPrice(double bookPrice);
}

For different members, define three specific strategy classes, and each class implements the method of calculating prices respectively.

/**
 * Created by hollis on 16/9/19. 初级会员
 */
public class PrimaryMember implements Member {

    @Override
    public double calPrice(double bookPrice) {
        System.out.println("对于初级会员的没有折扣");
        return bookPrice;
    }
}

/**
 * Created by hollis on 16/9/19. 中级会员,买书打九折
 */
public class IntermediateMember implements Member {

    @Override
    public double calPrice(double bookPrice) {
        System.out.println("对于中级会员的折扣为10%");
        return bookPrice * 0.9;
    }
}

/**
 * Created by hollis on 16/9/19. 高级会员,买书打八折
 */
public class AdvancedMember implements Member {

    @Override
    public double calPrice(double bookPrice) {
        System.out.println("对于高级会员的折扣为20%");
        return bookPrice * 0.8;
    }
}

The definitions of the above categories embody 封装变化the design principles, and changes in the specific discount methods of different members will not affect other members.

After defining the abstract strategy class and the specific strategy class, let's define the environment class. The so-called environment class is the class of the integrated algorithm. In this example, the cash register system. Members are integrated in a combined way.

/**
 * Created by hollis on 16/9/19. 书籍价格类
 */
public class Cashier {

    /**
     * 会员,策略对象
     */
    private Member member;

    public Cashier(Member member){
        this.member = member;
    }

    /**
     * 计算应付价格
     * @param booksPrice
     * @return
     */
    public double quote(double booksPrice) {
        return this.member.calPrice(booksPrice);
    }
}

This Cashier class is an environment class, and the definition of this class embodies 多用组合,少用继承two 针对接口编程,不针对实现编程design principles. Since the method of combination + interface is adopted here, we do not need to modify the Cashier class when launching super members later. Just define one SuperMember implements Membermore.

Let's define a client to test it out:

/**
 * Created by hollis on 16/9/19.
 */
public class BookStore {

    public static void main(String[] args) {

        //选择并创建需要使用的策略对象
        Member strategy = new AdvancedMember();
        //创建环境
        Cashier cashier = new Cashier(strategy);
        //计算价格
        double quote = cashier.quote(300);
        System.out.println("高级会员图书的最终价格为:" + quote);

        strategy = new IntermediateMember();
        cashier = new Cashier(strategy);
        quote = cashier.quote(300);
        System.out.println("中级会员图书的最终价格为:" + quote);
    }
}

//对于高级会员的折扣为20%
//高级会员图书的最终价格为:240.0
//对于中级会员的折扣为10%
//中级会员图书的最终价格为:270.0

As can be seen from the above example, the strategy pattern only encapsulates the algorithm and provides new algorithms to be inserted into the existing system. The strategy pattern does not decide when to use which algorithm. It is up to the client to decide which algorithm to use under what circumstances.

  • The focus of the strategy pattern

    • The focus of the strategy pattern is not how to implement algorithms, but how to organize and call these algorithms, so that the program structure is more flexible, with better maintainability and scalability.
  • Algorithmic equality

    • A great feature of the strategy pattern is the equality of each strategy algorithm. For a series of specific strategy algorithms, everyone's status is exactly the same. It is because of this equality that the algorithms can be replaced with each other. All policy algorithms are also independent of each other in terms of implementation, and there is no dependence on each other.

    • So this series of policy algorithms can be described like this: Policy algorithms are different implementations of the same behavior.

  • Uniqueness of runtime policy

    • During operation, the strategy pattern can only use one specific strategy implementation object at each moment. Although it can dynamically switch between different strategy implementations, only one can be used at the same time.
  • public behavior

    • It is common to see that all concrete strategy classes share some common behavior. At this time, these public behaviors should be put into the common abstract strategy role Strategy class. Of course, at this time, the abstract strategy role must be implemented with a Java abstract class instead of an interface. ([Strategy Mode of "JAVA and Mode"][5])

Advantages and disadvantages of strategy pattern

advantage

  • The strategy mode provides perfect support for the "open-close principle". Users can choose algorithms or behaviors without modifying the original system, and can also flexibly add new algorithms or behaviors.
  • The Strategy pattern provides a way to manage families of related algorithms. A hierarchy of strategy classes defines an algorithm or family of behaviors. Proper use of inheritance can move common code into the parent class, thereby avoiding code duplication.
  • Use the strategy pattern to avoid using multiple conditional (if-else) statements. Multiple conditional statements are not easy to maintain. It mixes the logic of which algorithm or behavior to adopt with the logic of the algorithm or behavior, and lists them all in a multiple conditional statement, which is more primitive and backward than the method of inheritance .

shortcoming

  • Clients must be aware of all policy classes and decide for themselves which one to use. This means that the client must understand the difference between these algorithms in order to select the appropriate algorithm class at the right time.
  • Because the strategy pattern encapsulates each specific strategy implementation separately into a class, if there are many alternative strategies, the number of objects will be considerable. The number of objects can be reduced to some extent by using the flyweight pattern.

Guess you like

Origin blog.csdn.net/zy_dreamer/article/details/132364399
Recommended