策略模式(Strategy pattern)

2020-04-07  本文已影响0人  吉他手_c156

策略模式的定义与特点

定义:
策略模式(Strategy Pattern)又叫政策模式(Policy Pattern),策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理。策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。通俗来说,就是:“准备一组算法,并将每一个算法封装起来,使得它们可以互换”,策略模式属于行为型模式。
优点:
1.算法和使用分离。两者独立变化,算法内容的调整不影响使用。
2.易于扩展。新的算法只要实现新的类,不需要对原有的框架进行修改,符合开闭原则
3.避免多重条件选择。
4.算法可复用。
缺点:
1.客户端必须知道所有的策略,并且自行选择使用哪一种策略。
2.代码中会产生非常多的策略类,增加维护难度。

策略模式涉及到三个角色

1.抽象策略(Strategy)角色:这是一个抽象角色,通常是一个接口或者抽象类。此角色给出所有具体策略类所要实现的接口。
2.具体策略(Concrete Strategy)角色:实现了抽象策略类的接口,提供具体算法实现。
3.环境(Context)角色:持有一个Strategy的引用,给客户端调用。

结构图

image.png

策略模式的实现

1.创建抽象策略类(AbstractStrategy)

/**
 * 抽象策略角色:规定了具体策略类要实现的接口,通常是抽象类或者接口
 */
public abstract class AbstractStrategy {

    public abstract void strategyMethod();
}

2.分别创建具体策略类A,B,C(ConcreteStrategyA,ConcreteStrategyB,ConcreteStrategyC)

/**
 * 具体策略类A:实现了抽象策略类的接口,提送算法的具体实现
 */
public class ConcreteStrategyA extends AbstractStrategy{
    @Override
    public void strategyMethod() {
        System.out.println("具体策略类ConcreteStrategyA的方法被表用了");
    }
}
/**
 * 角色策略类B:实现了抽象策略类的接口,提供算法的具体实现
 */
public class ConcreteStrategyB extends AbstractStrategy{
    @Override
    public void strategyMethod() {
        System.out.println("具体策略类ConcreteStrategyB的方法被表用了");
    }
}
/**
 * 具体策略类C:实现了抽象策略类的接口,提供算法的具体实现
 */
public class ConcreteStrategyC extends AbstractStrategy{
    @Override
    public void strategyMethod() {
        System.out.println("具体策略类ConcreteStrategyC的方法被表用了");
    }
}

3.创建环境类(Context)

/**
 * 环境类:持有一个 Strategy 的引用,供客户端调用
 */
public class Context {
    private AbstractStrategy strategy;
    public Context(AbstractStrategy strategy){
        this.strategy = strategy;
    }
    public void strategyMethod(){
        // 调用具体策略
        strategy.strategyMethod();
    }
}

4.具体调用

    public static void main(String[] args) {
        // 选择使用具体策略,缺点客户端必须知道所有策略,并选择一种策略使用
        // AbstractStrategy strategyA = new ConcreteStrategyA();
        AbstractStrategy strategyB = new ConcreteStrategyB();
        // AbstractStrategy strategyC = new ConcreteStrategyC();
        Context context = new Context(strategyB);
        // 调用具体策略类实现
        context.strategyMethod();
    }

5.调用结果


策略模式的应用实例(加减乘除运算)

1.抽象策略类(Strategy),提供运算的接口

/**
 * 抽象策略:规定了具体策略要实现的接口
 */
public interface Strategy {

    // 对元素 v 和 w 进行运算
    public int doOperation(int v,int w);
}

2.分别创建具体策略类,AddStrategy(加),SubtractStrategy(减),MultiplicationStrategy(乘),DivisionStrategy(除),实现抽象策略类的接口,完成结果运算

/**
 * 具体策略:提供加法运算
 */
public class AddStrategy implements Strategy{
    @Override
    public int doOperation(int v, int w) {
        System.out.println("Add Strategy :" + v + "+" + w);
        return v + w;
    }
}
/**
 * 具体策略:提供减法运算
 */
public class SubtractStrategy implements Strategy{
    @Override
    public int doOperation(int v, int w) {
        System.out.println("Sbutract Strategy " + v + "-" + w);
        return v - w;
    }
}
/**
 * 具体策略:提供乘法运算
 */
public class MultiplicationStrategy implements Strategy{
    @Override
    public int doOperation(int v, int w) {
        System.out.println("Multiplication Strategy :" + v + "*" + w);
        return v * w;
    }
}
/**
 * 具体策略:提供除法运算
 */
public class DivisionStrategy implements Strategy {
    @Override
    public int doOperation(int v, int w) {
        System.out.println("Division Strategy :" + v + "/" + w);
        return v / w;
    }
}

3.创建环境类(OperationContext),持有对 Strategy 类的引用,最终别客户端调用

/**
 * 环境类:持有 Strategy 引用 最终被客户端调用
 */
public class OperationContext {
    private Strategy strategy;
    public  OperationContext(Strategy strategy){
        this.strategy = strategy;
    }

    // 执行策略
    public int executeStrategy(int v,int w){
        // 调用具体类策略方法
        return this.strategy.doOperation(v,w);
    }
}

4.测试类

    public static void main(String[] args) {
        // 加法策略
        OperationContext add = new OperationContext(new AddStrategy());
        System.out.println("=========加法运算========");
        int addResult = add.executeStrategy(5,5);
        System.out.println("add strategy result = " + addResult);

        // 减法策略
        OperationContext subtract = new OperationContext(new SubtractStrategy());
        System.out.println("=========减法运算========");
        int subtractResult = subtract.executeStrategy(9,2);
        System.out.println("subtract strategy result = " + subtractResult);

        // 乘法策略
        OperationContext multiplication = new OperationContext(new MultiplicationStrategy());
        System.out.println("=========乘法运算========");
        int multiplicationResult = multiplication.executeStrategy(2,3);
        System.out.println("multiplication strategy result = " + multiplicationResult);

        // 除法策略
        OperationContext division = new OperationContext(new DivisionStrategy());
        System.out.println("=========除法运算========");
        int divisionResult = division.executeStrategy(10,5);
        System.out.println("division strategy result = " + divisionResult);
    }

5.调用结果

=========加法运算========
Add Strategy :5+5
add strategy result = 10
=========减法运算========
Sbutract Strategy 9-2
subtract strategy result = 7
=========乘法运算========
Multiplication Strategy :2*3
multiplication strategy result = 6
=========除法运算========
Division Strategy :10/5
division strategy result = 2
上一篇下一篇

猜你喜欢

热点阅读