设计模式-策略模式


策略模式,巧妙的利用了继承和多态的特性,让应用某些算法的功能随着场景的改变而改变;可以与工厂方法模式、代理模式,享元模式搭配使用从而避免对上层暴露太多具体的策略,违背迪米特原则。

简单实例

策略接口

public interface Strategy {
    /**
     * 定义抽象算法
     */
    void algorithm();
}

具体策略类

public class ConcreteStrategy1 implements Strategy{

    public void algorithm() {
        System.out.println("~~算法1被执行");
    }
}

具体策略类

public class ConcreteStrategy2 implements Strategy {
    public void algorithm() {
        System.out.println("~~算法2被执行");
    }
}

策略应用上下文

/**
 * @date 2019/1/7 11:05 策略应用上下文,维护算法生命周期
 */
public class Context {
    private Strategy strategy;

    public Context(Strategy _strategy) {
        this.strategy = _strategy;
    }

    public void exec() {
        this.strategy.algorithm();
    }

    public Strategy getStrategy() {
        return strategy;
    }

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

客户端

public class Client{
    public static void main(String[] args) {
        Strategy strategy = new ConcreteStrategy1();
        Context context  = new Context(strategy);
        //执行算法1
        System.out.println("执行算法1--------------------");
        context.exec();
        strategy = new ConcreteStrategy2();
        context.setStrategy(strategy);
        //执行算法2
        System.out.println("执行算法2--------------------");
        context.exec();
    }
}

输出结果:
在这里插入图片描述

不足

不足的地方是客户端需要感知到具体的策略,如果策略种类很多的话,难于维护。解决方式是采用混合模式

策略枚举方式

例子

以计算加减法作为一个例子来说明策略枚举:
策略枚举类

public enum Calculator {
    /**
     * 加法策略
     */
    ADD("+") {
        @Override
        public Integer exec(Integer a, Integer b) {
            return a + b;
        }
    },
    /**
     * 减法策略
     */
    SUB("-") {
        @Override
        public Integer exec(Integer a, Integer b) {
            return a - b;
        }
    };
    private String value;

    Calculator(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    /**
     * 抽象函数,具体枚举策略实现自身的算法
     *
     * @param a
     * @param b
     * @return
     */
    public abstract Integer exec(Integer a, Integer b);
}

客户端

public class Client {
    public static void main(String[] args) {
        Integer a = 5;
        Integer b = 3;
        System.out.println("开始加法计算,算子分别");
        System.out.println(Calculator.ADD.exec(a,b));
        System.out.println("开始减法计算");
        System.out.println(Calculator.SUB.exec(a,b));
    }
}

优势和不足

策略枚举方式的优势是:客户端可以很方便的知道具体的策略有哪些,并且如果命名规范的话,可以根据具体的枚举实例得知该算法的具体使用场景(比如Calculator.ADD.exec(a,b),可以很容易得出,这个枚举实例负责加法计算)。
不足之处是枚举类不易扩展,因为枚举类的项均为public、final的,因此我们使用该种方式的时候,要确认算法架构无变动,否则就要改动之前定义好的架构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值