探询策略模式
来源:互联网 发布:淘宝买太多了会怎么样 编辑:程序博客网 时间:2024/05/22 10:27
探询策略模式
策略模式
定义:又叫算法簇模式,就是定义了不同的算法族,并且之间可以互相替换,此模式让算法的变化独立于使用算法的客户(此处应该有图)
目的:让算法和对象分开;算法可以互相替换
注明:环境类封装未确定算法的使用,算法接口和算法具体实现类则构成了算法类层次。
优点:
- 算法类层次定义了一系列可供重用的算法或行为,使算法结构清晰化(对算法类本身有好处)
- 把算法封装在独立的算法类中,独立于环境类,可以易于切换,理解,拓展(对于算法类和环境类的搭配有好处)
- 消除了if-else条件语句
- 对于实现一个算法有更多的选择
策略模式Demo
策略环境类
/** * 策略模式环境类 * * @author Jax * */public class StrategyContext { StrategyInterface strategy; public StrategyContext(StrategyInterface strategy) { this.strategy = strategy; }; public void setStrategy(StrategyInterface strategy) { this.strategy = strategy; }; public String applyAlgorithm() { return strategy.algorithm(); }}
策略接口类
/** * 策略接口 * * @author Jax * */public interface StrategyInterface { // 策略算法 String algorithm();}
策略实现类A
public class ConcreteStrategyA implements StrategyInterface { @Override public String algorithm() { // 这是具体策略A的算法 return "策略A"; }}
策略实现类B
public class ConcreteStrategyB implements StrategyInterface { @Override public String algorithm() { // 这是具体策略B的算法 return "策略B"; }}
测试类的实现
public class Test { public static void main(String[] args) { //策略A的输出 StrategyContext context = new StrategyContext(new ConcreteStrategyA()); output(context.applyAlgorithm()); //策略B的输出 context.setStrategy(new ConcreteStrategyB()); output(context.applyAlgorithm()); //用匿名类输出 context.setStrategy(new StrategyInterface() { @Override public String algorithm() { // TODO Auto-generated method stub return "策略,匿名类"; } }); output(context.applyAlgorithm()); } // 输出结果 public static void output(String result) { System.out.println("algorithm result:" + result); }}
当一个具体策略只被用来使用一次时,也可以使用匿名类来声明和实例化这个具体策略类。
测试结果:
algorithm result:策略Aalgorithm result:策略Balgorithm result:策略,匿名类
单例策略
描述:当一个具体策略是被设计用来重复使用时,它的类通常实现为私有的静态成员类,然后通过公有的静态final域被导出,其类型为该策略接口。这样可以提高性能(如果程序经常请求创建相同的对象,并且创建对象的代价很高,那么用静态final域来表示这个对象则可以提高程序的性能)。
单例策略Demo
/** * 具体策略单例 * * @author Jax * */public class ConcreteSrategySingletonHost { private static class StrategyImpl implements StrategyInterface { @Override public String algorithm() { // TODO Auto-generated method stub return "策略,单例"; } } public static final StrategyImpl THE_STRATEGY = new StrategyImpl();}
测试类:
public class Test { public static void main(String[] args) { //静态单例策略的输出 StrategyContext context2 = new StrategyContext(ConcreteSrategySingletonHost.THE_STRATEGY); output(context2.applyAlgorithm()); } // 输出结果 public static void output(String result) { System.out.println("algorithm result:" + result); }}
输出结果:
algorithm result:策略,单例
泛型策略
描述:泛型的使用可以在编译前就有效减少类转换异常的发生,使类或方法的实现变得简单安全。描述算法的策略常常用到了泛型单例工厂,这样可以对于一个未知的类进行操作,并且可以用对泛型的修饰来控制这个类的范围。
泛型策略Demo
带泛型的策略接口类
public interface GenericStrategy<T> { // 这个接口设计仅作为一个最简单的例子 T apply(T arg);}
具体策略类,泛型单例工厂
public class GenericStategySingletonHost { private static GenericStrategy<Object> THE_STRATEGY = new GenericStrategy<Object>() { @Override public Object apply(Object arg) { // 这只是一个最简单的例子,这里应是泛型单例的具体操作,用Obj对象代替泛型对象 return arg; } }; // 这里之所以可以消除非受检警告,是我们必须确定apply算法实现的时候不会出现类型转换异常 @SuppressWarnings("unchecked") public static <T> GenericStrategy<T> getTheStrategy() { return (GenericStrategy<T>) THE_STRATEGY; }}
测试类
public class Test { public static void main(String[] args) { GenericStrategy<String> stringGenericStrategy = GenericStategySingletonHost.getTheStrategy(); String stringArg = "String参数"; output("————泛型算法,泛型为String————结果为:" + stringGenericStrategy.apply(stringArg)); GenericStrategy<Integer> integerGenericStrategy = GenericStategySingletonHost.getTheStrategy(); Integer intergerArg = 1; output("————泛型算法,泛型为Interger————结果为:" + integerGenericStrategy.apply(intergerArg)); if (stringGenericStrategy.equals(integerGenericStrategy)) { output("————说明泛型为String的泛型算法对象和泛型为Interger的泛型算法对象是同一个————"); } } // 输出结果 public static void output(String result) { System.out.println("algorithm result:" + result); }}
输出结果:
algorithm result:————泛型算法,泛型为String————结果为:String参数algorithm result:————泛型算法,泛型为Interger————结果为:1algorithm result:————说明泛型为String的泛型算法对象和泛型为Interger的泛型算法对象是同一个————
结语
本文第一节,介绍设计模式中第18条,策略模式。策略是什么?策略代表一个行为,也可以说它是一个函数。它可以针对输入的参数进行计算,进行修改,或者进行比较来输出结果。不同业务需求下,可能对应了不同的策略方式,如果我们用if-else来做处理,或者把不同的策略都写到同一个类中,会造成代码的混杂和逻辑层次的混乱。所以我们可以将不同策略具体实现抽象提炼成策略接口。这样我们就可以把 策略具体实现类和调用策略的环境类分开,类优化代码和逻辑关系。
本文第二节,介绍的是策略的单例实现。这是一种针对策略模式的优化方案。对于重复使用的策略,这种方式可以避免重复创建具体策略类对象。来改进代码的性能。
本文第三节,介绍的是策略单例实现+泛型单例工厂。泛型大家并不陌生,但是对于泛型的细致的使用可能也并不熟悉。所以对这一节的原理的理解会比较有难度。为什么例子中对于泛型策略接口方法的实现用Object来代替E呢?为什么这里测试代码的输出结果和参数一模一样呢,这样有什么意义呢?为什么两个不同泛型的策略对象实际上是同一个对象呢?
这里先回答关于Demo的设计。即解释测试代码中输出结果和参数一模一样的意义是什么。
首先,Demo中对于带泛型的策略接口方法的设计,十分的简单。其实,通过对泛型的修饰,比如多个泛型,泛型必须继承的父类,泛型必须的被继承的子类等,都可以通过代码进行描述,参数和返回结果都会十分多变复杂。这取决于策略意图本身。我这里只是举了个最简单的栗子,即输入什么类型,我返回什么类型。
其次,Demo中对于带泛型的策略接口的实现,也非常的简单。过程是在接口方法的限制下,是对于任意对象的任意操作。鉴于这只是个Demo,我取了最简单的实现方法,即什么都没做——就把这个参数原封不动地返回出去了而已。
所以,在Demo的测试类下,我们看到的结果只是参数的简单输出而已。其实,在这个过程中,有太多可以改变的地方。
最后,这个Demo想表达的意思,还有一个,在泛型不同的情况下,策略依然可以用单例来优化性能。最后一个输出结果我们可以看出,泛型不同的两个策略方法,其实都是那个单例而已,它并没有改变。
- 探询策略模式
- 探询国际工程项目信息化管理策略
- C++ Practise14:探询路径
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- HDU-2102-A计划(BFS)
- linux中export的作用和source命令
- Jquery中ajax方法data参数的用法
- UIL doesn't support scheme(protocol) by default You should implement this support yourself
- 2.4函数句柄
- 探询策略模式
- 新手自学ios 之 利用YYModel封装网络请求返回model
- 线程和进程
- oracle 同步数据库表数据
- openfalcon - agent - fastdfs
- using Regular Expressions to Look References in Source Insight
- Java连接Oracle数据库的简单示例
- 解决低版本的xcode不能打开xcode8.0
- 视频播放器的屏幕手势适配