分类: Java
2013-01-20 01:20:55
策略模式是对算法进行封装的一种方法,将算法和算法的使用解耦出来。一类的算法都实现相同的接口,将这些不同的算法包装到一系列的策略类里。客户端通过实现对接口的调用,按照需求调用所需的策略,使用其中包装的算法,达到所需的目的。
从上图可以清晰的知道,在这个模式中主要涉及三个参与者,客户端(上下文,Context),抽象策略及具体策略。
客户端,持有抽象策略的引用,通过该引用来调用具体策略中的算法。
抽象策略,是具体策略所共有的接口,一般由接口来充当其角色,给出了具体策略所要实现的接口。
具体策略,实现抽象策略所有的接口,将每种具体的算法包装到具体的策略中。
很多书和博客中给出的例子,大多数都是关于购物折扣问题的,这个问题比较简单易懂。意思就是通过策略模式将原本的判断逻辑和算法执行过程分离开来。当需要新的计算方法时,添加一个实现该抽象策略接口新的具体策略类,通过该新的具体策略类来实现该功能。对系统原有代码不需做任何修改。形象一点来说,系统需要一个新配件,我们按照系统规范做一个新配件,安装到系统中去,系统可以实现完美调用的这个过程。
在这篇博文中,我举一个计算文件摘要的例子。常用的计算摘要的算法主要是MD5,SHA-1,SM3等算法。我们现在并不关心它们计算的细节有何差别,只需要知道一点--它们都是将输入的字符或字符串经过一系列复杂的计算输出一定长度的字符串(尽管它们输出字符串长度不一定相同)。
定义一个公共的接口Hash:
1: public interface Hash {
2:
3: public byte[] digest(byte[] str);
4: public byte[] digest(String str);
5: }
三个具体策略类如下
MD5Digest:
1: public class MD5Digest implements Hash {
2:
3: public byte[] digest(byte[] str) {
4: byte[] digest = new byte[16];
5: //MD5计算过程
6: return digest;
7: }
8:
9: public byte[] digest(String str) {
10: byte[] digest = new byte[16];
11: //MD5计算过程
12: return digest;
13: }
14: }
SHADigest:
1: public class SHA1Digest implements Hash {
2:
3: public byte[] digest(byte[] str) {
4: byte[] digest = new byte[32];
5: //SHA-1 计算过程得到digest
6: return digest;
7: }
8:
9: public byte[] digest(String str) {
10: byte[] digest = new byte[32];
11: //SHA-1 计算过程得到digest
12: return digest;
13: }
14: }
SM3Digest:
1: public class SM3Digest implements Hash {
2:
3: public byte[] digest(byte[] str) {
4: byte[] digest = new byte[32];
5: //SM3 计算过程得到digest
6: return digest;
7: }
8:
9: public byte[] digest(String str) {
10: byte[] digest = new byte[32];
11: //SM3计算过程得到digest
12: return digest;
13: }
14: }
客户端即上下文类为:
1: public class Context {
2:
3: Hash hash = null;
4: byte[] digest = null;
5: public Context(Hash hast){
6: this.hash = hast;
7: }
8:
9: public void calculate(String str){
10: digest = hash.digest(str);
11: }
12: }
从上面的叙述中,可以总结一下,在什么情况下适合使用策略模式
策略模式的优点:
策略模式的缺点: