什么是策略模式?
策略模式就是定义了一系列算法的方法,这些算法完成的都是相同的工作,只是它们具体的实现不一样,但它们可以通过以相同的方式调用所有的算法,减少了算法类与使用这些算法类之间的耦合。
还是以两个数的运算为例,运算中的加法、减法、乘法等等就是算法的具体实现,而运算则是这些算法的公共行为。
package com.shijinnan.strategy;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import com.shijinnan.strategy.Operation;
import com.shijinnan.consts.Const;
public class Factory
{
private Operation oper;
/*
* 存放算法类对象的容器
*/
private static Map<String, Operation> map = new HashMap<String, Operation>(
Const.DEFAULT);
/**
* 利用反射机制,加载这个类时利用反射机制, 动态加载算法类,生成算法类对象
*/
static
{
init("path");
}
public Factory(String strategy)
{
oper = map.get(strategy);
}
/**
* 初始化方法,加载文件中的类
*/
private static void init(String s)
{
String filePath = "D:\\class.properties";
Properties pro = new Properties();
FileInputStream in = null;
try
{
in = new FileInputStream(filePath);
pro.load(in);
Iterator<String> it = pro.stringPropertyNames().iterator();
String key = null;
String values = null;
Class<?> cls = null ;
Operation oper = null;
while (it.hasNext())
{
key = it.next();
values = pro.getProperty(key);
cls= Class.forName(values);
oper = (Operation) cls.newInstance();
map.put(key, oper);
}
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (ClassNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (InstantiationException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IllegalAccessException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
if (in != null)
{
try
{
in.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
System.out.println(map);
}
/**
* des:两个数的运算
*
* @param number1
* @param number2
* @return 结果
* @throws Exception
*/
public double getResult(double number1, double number2) throws Exception
{
if(oper != null)
{
return oper.operate(number1, number2);
}
else
{
throw new Exception();
}
}
}
首先,Factory类利用java中的反射原理,动态生成对应算法类的对象并放到一个容器里。配置文件class.properties:
sub=com.shijinnan.strategy.SubOperation
把运算的行为抽象出一个父类Operation
package com.shijinnan.strategy;
public abstract class Operation
{
/**
* des:运算的方法
* @return 结果
*/
public abstract double operate(double num1, double number2);
}
每一个要实现的运算算法都继承此类,实现operate方法。然后只要将对应的算法实现类,及外部调用的键值放到class.properties文件中就行了。而外部想调用对应的算法类,只需要将对应约定的值,传到Factory构造器里,调用getResult()方法就可以调用对应的算法进行运算了。
可以看出,我们要增加一个两个数的运算算法,只要它继承Operation类,实现operate方法,再在对应的配置文件加配置就可以了。
随便聊一下,如果用过加密算法的公共架包,使用的就是这个设计模式,只需要将对应算法的字段比如说MessageDigest.getInstance(“MD5”); 就可以使用md5算法对字段进行加密了:
BigInteger bigInteger=null;
try {
MessageDigest md = MessageDigest.getInstance(KEY_MD5);
byte[] inputData = inputStr.getBytes();
md.update(inputData);
bigInteger = new BigInteger(md.digest());
} catch (Exception e) {e.printStackTrace();}
System.out.println("MD5加密后:" + bigInteger.toString(16));
return bigInteger.toString(16);