Strategy (Strategy) mode

  Policy model is intended for a set of algorithms, each algorithm is encapsulated into a separate class have a common interface, so that that they can replace each other. Strategy Mode makes the algorithm changes can occur without affecting the client.

  Strategy mode is equivalent pluggable algorithm. It may be such that the interface remains unchanged in the case of the specific algorithm used interchangeably.

 1 Introduction

  Strategy Mode is a package of algorithms, and the algorithm is the responsibility of using the algorithm itself divided, assigned to different objects management. Strategy pattern usually a series of algorithms to package a series of strategies inside the class, as an abstract policy subclasses. That is: preparing a set of algorithms, each algorithm and encapsulated, so that they can be interchanged.

  Class schematic diagram as follows:

  

2. Structure

  Strategy also called policy (Policy) mode. The following structure:

This model involves the three roles:

(1) Environment (Context) role: to hold a reference to a Strategy

(2) an abstract strategy (Strategy) Role: This is an abstract role, usually implemented by an interface or abstract class. This role gives the interface to all of the specific policy class.

(3) specific strategies (ConcreteStrategy), packaging related algorithm or behavior.

 

 Pseudo-code as follows:

package cn.qlq.strategy;

public class Context {

    private Strategy strategy;

    public void contextInterface() {
        strategy.strategyInterface();
    }

    public Strategy getStrategy() {
        return strategy;
    }

    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }

}
package cn.qlq.strategy;

public interface Strategy {

    void strategyInterface();
}
Package cn.qlq.strategy; 

public  class ConcreteStrategy the implements Strategy { 

    @Override 
    public  void strategyInterface () { 
        System.out.println ( "specific algorithm logic" ); 
    } 

}

 

   In general, the pattern of meaningful strategy will involve more than the application of a specific policy role. The above code can be used as the backbone of a policy model.

 

3. mode of realization

 Note specific region:

(1) all of the specific policy class has some public behavior. This time we should put these public behavior into a common strategy role-Strategy abstract class inside. This time abstract strategy role must not be used interface with an abstract class.

(2) Strategy Mode can only use a policy object at every moment, but sometimes one application at the same time linked to several policy object. In other words, when the application starts, all policy object has been created it, and the application can be exchanged between several policy object. It is only in the case of Policy Objects will not spend a lot of computer memory resources to be viable, it needs only in case the policy object initialization will take a long time.

 

Suppose now that the sale of all kinds of books to design a e-commerce website shopping cart system. All books within the site may have a discount, roughly divided into: no discount, minus a fixed price above 2 million, according to the proportion of 3% discount.

Use strategy pattern described in the words of these different algorithms are different strategies specific role: NoDiscountStrategy a representation algorithm; FlatDiscountStrategy algorithm represents two; PercentageStrategy representation algorithm III.

FIG class as follows:

 

code show as below:

package cn.qlq.strategy;

public abstract class DiscountStrategy {

    /**
     * 单价
     */
    protected float price;

    /**
     * 数量
     */
    protected int numbers;

    abstract float calculateDiscount();

    public DiscountStrategy(float price, int numbers) {
        super();
        this.price = price;
        this.numbers = numbers;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

    public int getNumbers() {
        return numbers;
    }

    public void setNumbers(int numbers) {
        this.numbers = numbers;
    }

}

  这个是一个抽象类,而抽象类不可能有实例。上面的两个属性以及构造子是为了约束具体策略类应当赋值给单价和数量,然后调用 calculateDiscount 算出折扣。

 

package cn.qlq.strategy;

public class NoDiscountStrategy extends DiscountStrategy {

    public NoDiscountStrategy(float price, int numbers) {
        super(price, numbers);
    }

    @Override
    float calculateDiscount() {
        return 0;
    }

}
package cn.qlq.strategy;

public class FlatDiscountStrategy extends DiscountStrategy {

    /**
     * 折扣金额
     */
    private float discountAmount;

    public FlatDiscountStrategy(float price, int numbers, float discountAmount) {
        super(price, numbers);

        this.discountAmount = discountAmount;
    }

    @Override
    float calculateDiscount() {
        return discountAmount * numbers;
    }

    public float getDiscountAmount() {
        return discountAmount;
    }

    public void setDiscountAmount(float discountAmount) {
        this.discountAmount = discountAmount;
    }

}
package cn.qlq.strategy;

public class PercentageStrategy extends DiscountStrategy {

    /**
     * 折扣比例
     */
    private float discountPercent;

    public PercentageStrategy(float price, int numbers, float discountPercent) {
        super(price, numbers);

        this.discountPercent = discountPercent;
    }

    @Override
    float calculateDiscount() {
        return discountPercent * price * numbers;
    }

    public float getDiscountPercent() {
        return discountPercent;
    }

    public void setDiscountPercent(float discountPercent) {
        this.discountPercent = discountPercent;
    }

}

 

何时使用何种策略?

  策略模式并不负责决定使用哪个具体策略,这种决定应该由客户端决定。策略模式仅仅封装算法。而且客户端在使用不同的策略模式的同时需要了解不同策略模式需要的参数。

  测试模式不适合于处理同时嵌套多于一个算法的清形。一般而言,策略模式只适用于在几种算法中选择一种。

  比如在上面基础增加了第四种法则:在所有的折扣算法计算后,总的折扣不能超过1000。这也就意味着客户端需要使用上面算法一、二、三计算出折扣总值,再使用算法四。这就需要再借助于装饰者模式

 

4.  适用场景与优缺点

1.  适用场景

在下面的场景下应当使用策略模式:

(1)一个系统有许多类,它们之间的区别仅在于它们的行为。

(2)一个系统中需要动态地在几种算法中选择一种。

(3)一个算法使用的数据不需要客户端知道

(4)一个对象有多种行为,如果不用恰当的模式就只能使用多重的条件选择语句来实现。此时,用策略模式可以避免难以维护的多重选择,并体现面向对象的思想。

 

2.  优点:

(1)策略模式提供了管理相关算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类中,从而避免重复的代码。

(2)策略模式提供了可以替换继承关系的办法。继承使得动态改变算法或行为变得不可能。

(3)使用策略模式可以避免使用多重条件判断语句。

 

3.  缺点:

(1)客户端必须知道所有的具体策略类,并自行决定使用哪种策略类。

(2)策略模式造成很多的策略类。有时候可以通过把依赖于环境的状态保存到客户端,而将策略类设计成可共享的。这样策略类实例可以被不同客户端使用。换言之,可以使用享元模式来减少对象的数量。

 

5.  操作系统中的策略模式-windows屏幕保护程序的设置

  每一个屏幕保护程序都有不同的参数设置,如下:

 

  每一种程序提供不同的算法,在屏幕上放映3D文字、图片等。用户需要为每一种程序设定所需的参数。策略模式提供了解决这个问题的方案。当用户选中一个屏幕保护程序后就需要设定程序的参数。如下是3D文字所需要的参数:

 

  这是典型的策略模式的应用:每一个屏幕保护程序都有一个自己的参数设定窗口。这个窗口便是具体策略角色,它代表不同的算法;用户可以选择一个算法并设定其参数;所有的参数设定窗口都有自恰的界面设计,让用户相信策略对象后面有一个共同的抽象接口约束它们,它就是抽象策略角色。

 

Guess you like

Origin www.cnblogs.com/qlqwjy/p/11238682.html