策略模式小试
来源:互联网 发布:驱动精灵for mac 编辑:程序博客网 时间:2024/06/03 21:27
策略模式是一种非常简单、使用非常广泛的设计模式。
转载请注明出处:http://www.cnblogs.com/zrtqsk/p/3732516.html,谢谢!
一、介绍
看一下《研磨设计模式》里的介绍——定义一系列的算法,把它们一个个封装起来,并且使他们可相互替换。本模式使得算法可独立于使用它的客户而变化。
策略模式的本质是——分离算法、选择实现。
什么意思呢?我们知道什么是算法,简单而言就是计算某种事物的方法。我们都知道排序,最常见的排序包括冒泡排序、快速排序、堆排序、直接插入排序等等很多。这里的排序方法就是算法。每一种排序都有各自不同的特点,适用于不同的情况。如果将这些算法封装起来,以便随时选择切换,这就是策略模式的本质了。
那么怎么实现策略模式呢?说白了就是从众多算法实现中抽象出一个接口,然后众算法都实现这个接口,然后调用者呢,就持有这个接口,于是就可以使用这个算法了。
理解策略模式,可以从“策略”二字着手。什么是策略?就是解决问题的方法、对策!策略模式,就是切换方法的模式!就这么简单。怎么切换方法呢?将方法放进接口,让不同的策略去实现这个接口,然后就可以自由的切换了。
任何的算法实现,我们都可以用策略模式将其包装一下,实现算法的自由切换。
二、我的实现
假设现在有一个游戏。我们设定正常情况下,玩家获得的游戏分数是固定的。玩家红名时获得分数减半;节假日,所有玩家获得分数翻倍;游戏会员获得分数加成,加成效果与会员等级有关;为了操作方便,还可以指定分数加成值。现在我们把这个分数加成算法包装一下。
1、我们先创建一个分数加成接口,如下:
1 package strategy;2 3 public interface PointAddition {4 5 double getAddition(double point);6 }
2、下面是会员分数加成,与会员等级有关:
1 package strategy; 2 3 public class VipAddition implements PointAddition { 4 5 private int level = 0; 6 7 public VipAddition(int level) 8 { 9 this.level = level;10 }11 12 @Override13 public double getAddition(double point)14 {15 return point * (1 + 0.5 +level * 0.05);16 }17 18 }
3、玩家红名状态:
1 package strategy; 2 3 //玩家红名时,获得分数减半 4 public class RedNameAddition implements PointAddition { 5 6 @Override 7 public double getAddition(double point) 8 { 9 return point * 3;10 }11 }
4、节假日分数加成:
1 package strategy; 2 3 public class FestivalAddition implements PointAddition{ 4 5 @Override 6 public double getAddition(double point) 7 { 8 return point * 2; 9 }10 }
5、指定分数加成
1 package strategy; 2 3 public class SpecifiedAddition implements PointAddition{ 4 5 private double specifiedAddition = 0; 6 public SpecifiedAddition( double specifiedAddtion) { 7 this.specifiedAddition = specifiedAddition; 8 } 9 10 @Override11 public double getAddition(double point)12 {13 return point * (1 + specifiedAddition);14 } 15 }
6、由于玩家可能同时处于多种状态,所以各种算法不应单独计算。我们用一个上下文类来处理。如下:
1 package strategy; 2 3 import java.util.ArrayList; 4 import java.util.Collection; 5 6 public class PointContext { 7 8 //基本分数 9 private double basePoint = 0;10 //分数折扣11 private double allDiscount = 0;12 13 public PointContext(double basePoint)14 {15 this.basePoint = basePoint;16 }17 18 //所有分数加成的状况19 private Collection<PointAddition> additions = null;20 21 //增加分数加成情况22 public void addPointAddtion(PointAddition add)23 {24 if (additions == null)25 {26 additions = new ArrayList<PointAddition>();27 28 }29 additions.add(add);30 }31 32 //计算总分数33 public double calculatePoints()34 {35 if (additions == null)36 {37 allDiscount = 0;38 }39 for (PointAddition add : additions)40 {41 allDiscount += add.getAddition(1);42 }43 return basePoint * allDiscount;44 }45 }
7、大功告成!下面来测试一下:
1 package strategy; 2 3 public class Test { 4 5 public static void main(String[] args) 6 { 7 // 节假日分数加成 8 FestivalAddition festivalAdidtion = new FestivalAddition(); 9 // VIP等级为5的分数加成10 VipAddition vipAddition = new VipAddition(5);11 // 红名分数减半12 RedNameAddition redNameAddtion = new RedNameAddition();13 // 分数上下文,持有所有的加成状态,并设置基础分为100014 PointContext context = new PointContext(1000);15 // 添加各种加成状态16 context.addPointAddtion(vipAddition);17 context.addPointAddtion(festivalAdidtion);18 context.addPointAddtion(redNameAddtion);19 // 输出总分数20 System.out.println("我的总分:" + context.calculatePoints());21 }22 }
结果如下:
我的总分:4250.0
我这里的策略模式是一般策略模式的变种,专门用于这种算法需要叠加的状况。而传统的策略模式仅仅是使某一个算法可以选择替换。
这里需要注意的是这个分数上下文类。计算分数可能有很多种状况,每一种算法需要使用、传入的数据不尽相同。一般为了方便,可以让这个分数上下文类来持有所有的数据,然后算法需要什么就取什么。
侠义的策略模式是算法的切换,而广义的策略模式可以是各种场景、模块的切换。下面我们使用策略模式来讲解一下容错恢复机制。
三、容错恢复机制
什么是容错恢复呢?就是如果程序出错了,程序能够容忍这些错误,用某种方式保证仍然保证程序能够运行下去。
像刚才的算法比较简单,一般不会发生什么异常。我们将它改一下:
1、我们创建一个正常情况下,分数无任何加成的类:
package strategy;public class NomalAddition implements PointAddition { @Override public double getAddition(double point) { return point; }}
2、我们把上下文类PointContext的计算分数的方法改一下,如下:
1 //计算总分数 2 public double calculatePoints() 3 { 4 if (additions == null) 5 { 6 allDiscount = 0; 7 } 8 for (PointAddition add : additions) 9 { try {10 allDiscount += add.getAddition(1); 11 }catch(Exception e) {12 //容错恢复13 allDiscount += new NomalAddition().getAddition(1);14 }15 }16 return basePoint * allDiscount;17 }
当某个分数加成算法出现异常的时候,用普通的分数加成算法代替。
容错恢复机制不仅可以用于算法,各种模块之间的切换都可以使用,是一种非常实用的异常解决机制。
- 策略模式小试
- 策略模式小例子
- 策略模式小例子
- 策略模式小练习
- 策略模式小练习
- 策略模式的小例子
- 小话设计模式四:策略模式
- 策略模式——小白入门
- 策略模式使用的小技巧
- 小话设计模式(二十一)策略模式
- 小哥哥带你撸设计模式之---策略模式
- 【小程序】用策略模式完成自定义类的排序
- Java Design Demo--策略模式 (图片滤镜小工程)
- C++ 工厂模式和策略模式以及单件模式小练习
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 字符集
- OCP 1Z0 051 49
- 看书小记7(《C专家编程》)
- Linux网络协议栈之数据包处理过程(非技术人员勿看)
- J2EE环境安装配置
- 策略模式小试
- 摩托车继承自行车和机动车
- 美国VPN你懂的!!
- the C programming language 练习
- 组合模式小试
- mini2440下载到nandflash中时地址设置是0x30000000
- ADO.net数据库访问技术(一)
- Nginx中502和504错误详解
- lubuntu下安装SDL