概述
策略模式是指包含一个策略接口和一组实现这个接口的策略类,它的应用有很多,其中一种就是取代if…else语句,来看个例子
demo
有这样一个需求,一个文件里可能存放着大概0~100G的用逗号分隔开的数字,要求根据文件的大小选择不同的算法,对文件中的数字进行排序
一开始代码是这样的
public void sortFile(String filePath){
File file = new File(filePath);
long fileSize = file.length();
if (fileSize < 6 * GB){
sortfactory.getSort("QuickSort").sortChar(filePath);
quickSort quickSort = new quickSort();
quickSort.sortChar(filePath);
}else if (fileSize < 10 * GB ){
externalSort externalSort = new externalSort();
externalSort.sortChar(filePath);
}else if (fileSize < 100 * GB){
concurrentExternalSort sort = new concurrentExternalSort();
sort.sortChar(filePath);
}else {
mapreduceSort mapreduceSort = new mapreduceSort();
mapreduceSort.sortChar(filePath);
}
}
通过观察我们知道所有的代码都需要一个排序算法,根据策略模式的要求,引入一个接口
public interface sort {
void sortChar(String filePath);
}
不同的算法都实现这个接口,并在其中实现排序,类似这样,其他算法也如此
public class concurrentExternalSort implements sort{
@Override
public void sortChar(String filePath) {
System.out.println("多线程排序算法");
}
}
一般来说会在工厂中注册这些方法,当用的时候,根据type即可取出
public class sortfactory {
private static ConcurrentHashMap<String, sort> storeSortClass = new ConcurrentHashMap<>();
static {
storeSortClass.put("QuickSort",new quickSort());
storeSortClass.put("MapreduceSort",new mapreduceSort());
storeSortClass.put("externalSort",new externalSort());
storeSortClass.put("concurrentExternalSort",new concurrentExternalSort());
}
public static sort getSort(String type){
return storeSortClass.get(type);
}
}
也就有了第二版的改造,这里我们传一个type到工厂中便取得相应的排序类了
private static final long GB = 1000 * 1000 * 1000;
public void sortFile(String filePath){
File file = new File(filePath);
long fileSize = file.length();
if (0 < fileSize && fileSize < 6 * GB){
sortfactory.getSort("QuickSort").sortChar(filePath);
}else if (6 * GB < fileSize && fileSize < 10 * GB ){
sortfactory.getSort("externalSort").sortChar(filePath);
}else if (fileSize < 10 * GB && fileSize < 100 * GB){
sortfactory.getSort("concurrentExternalSort").sortChar(filePath);
}else {
sortfactory.getSort("MapreduceSort").sortChar(filePath);
}
}
如果能够取掉if…else的话就更好了,首先if…else判断的是一个范围,那么就可以设计一个范围的开始和结束,调用者传一个比较值进来,那么通过for循环一个个判断,就可以根据范围获取到相应的排序算法了
public class sortnoif {
private static final long GB = 1000 * 1000 * 1000;
private static List<sortnoif> allSortClass = new ArrayList<>();
private long start;
private long end;
private sort sort;
static {
allSortClass.add(new sortnoif(0,6 * GB,sortfactory.getSort("QuickSort")));
allSortClass.add(new sortnoif(6 * GB,10 * GB,sortfactory.getSort("QuickSort")));
allSortClass.add(new sortnoif(10 * GB,100 * GB,sortfactory.getSort("QuickSort")));
allSortClass.add(new sortnoif(100,Long.MAX_VALUE,sortfactory.getSort("QuickSort")));
}
public sortnoif(long start, long end, sort sort){
this.start = start;
this.end = end;
this.sort = sort;
}
public static sortnoif getSort(long size){
if (size<=0){
throw new IllegalArgumentException("文件大小不能为0");
}
for (sortnoif oneSort:allSortClass) {
if (oneSort.getStart()< size && size < oneSort.getEnd()){
return oneSort;
}
}
return null;
}
public long getStart() {
return start;
}
public long getEnd() {
return end;
}
public learn.clms.clms.yl.sort getSort() {
return sort;
}
}
所以你可以看到,用策略模式取代判断范围的if…else语句后,代码会变得简洁
public class sortfile3 {
private static final long GB = 1000 * 1000 * 1000;
public void sortFile(String filePath){
File file = new File(filePath);
long fileSize = file.length();
sortnoif sortData = sortnoif.getSort(fileSize);
sort sort = sortData.getSort();
sort.sortChar(filePath);
}
public static void main(String[] args) {
sortfile3 sortfile = new sortfile3();
sortfile.sortFile("D:/ccc.txt");
}
}