[design pattern](1) Strategy
引言
最近,在学习设计模式相关的知识。本博客主要想讲一讲策略模式,这也是我学习的第一个模式。写下这篇博客,主要想记录下个人的一点理解,也是想通过写博客的方式来加深对与Strategy的一点理解。以下的内容如果有什么说的不对的地方,还请各位大神指正。
思考题
首先我们来思考下面的一个问题:
问题:写出冒泡排序和快速排序算法,并且根据传参不同,使用不同的排序算法排序。
首先,来看没有使用设计模式的代码是什么样子:
SortAlgorithm.java:
import java.util.Random;
import java.util.Arrays; public class SortAlgorithm {
private static int index = 10000;
private static int randomMax = 50000;
private static Integer[] oldOrder = new Integer[index];
private static Random random = new Random();
static {
for(int i = 0; i < index; i++) {
oldOrder[i] = random.nextInt(randomMax);
}
} //通过设置算法名称来决定用什么算法
private String algorithmName; public static void main(String... args) {
SortAlgorithm sortAlgorithm = new SortAlgorithm();
Integer[] oldOrder1 = Arrays.copyOf(oldOrder, index);
Integer[] oldOrder2 = Arrays.copyOf(oldOrder, index); sortAlgorithm.setAlgorithmName("bubble");
//System.out.println(String.format("BubbleSort sort before order:%s", Arrays.asList(oldOrder1).toString()));
long startTime = System.currentTimeMillis();
Integer[] newOrder1 = sortAlgorithm.executeAlgorithm(oldOrder1);
System.out.println(String.format("BubbleSort take time:%s", System.currentTimeMillis() - startTime));
//System.out.println(String.format("BubbleSort sort after order:%s", Arrays.asList(newOrder1).toString())); sortAlgorithm.setAlgorithmName("quick");
//System.out.println(String.format("QuickSort sort before order:%s", Arrays.asList(oldOrder2).toString()));
startTime = System.currentTimeMillis();
Integer[] newOrder2 = sortAlgorithm.executeAlgorithm(oldOrder2);
System.out.println(String.format("QuickSort take time:%s", System.currentTimeMillis() - startTime));
//System.out.println(String.format("QuickSort sort after order:%s", Arrays.asList(newOrder2).toString()));
} public Integer[] executeAlgorithm(Integer[] oldOrder) {
if("bubble".equals(algorithmName)){
return sortBubble(oldOrder);
}else if("quick".equals(algorithmName)) {
return sortQuick(oldOrder);
}
return null;
} public void setAlgorithmName(String algorithmName) {
this.algorithmName = algorithmName;
} private Integer[] sortBubble(Integer[] oldOrder) {
for(int i = 1; i < oldOrder.length; i++) {
for(int j = 0; j < oldOrder.length - i; j++) {
if(oldOrder[j] > oldOrder[j + 1]) {
Integer temp = oldOrder[j];
oldOrder[j] = oldOrder[j + 1];
oldOrder[j + 1] = temp;
}
}
}
return oldOrder;
} private Integer[] sortQuick(Integer[] oldOrder) {
partSort(oldOrder, 0, oldOrder.length - 1);
return oldOrder;
} private void partSort(Integer[] oldOrder, int start, int end) {
if(start < end) {
int middle = swaps(oldOrder, start, end);
partSort(oldOrder, start, middle);
partSort(oldOrder, middle + 1, end);
}
} private int swaps(Integer[] oldOrder, int start, int end) {
Integer temp = oldOrder[start];
for(;start < end;) {
for(;start < end && temp <= oldOrder[end]; end--);
if(start < end) {
oldOrder[start] = oldOrder[end];
start++;
}
for(;start < end && temp > oldOrder[start]; start++);
if(start < end) {
oldOrder[end] = oldOrder[start];
end--;
}
}
oldOrder[start] = temp;
return start;
}
}
print:
BubbleSort take time:717
QuickSort take time:14
上面是我的实现,所有的代码都集中在SortAlgorithm一个class里面。那么试想一下这时候如果我们想再增加一个选择排序,那么我们需要修改SortAlgorithm类,这样我们就违背了 开闭原则 。因此我们要想办法把修改变为增加。那么怎么样才能将修改变为增加呢?通过使用 strategy 可以做到。
介绍strategy
- 定义: 定义一系列的算法,将每一个算法封装起来,并且让这些封装的算法之间可以相互替换。该模式可以使算法独立于使用它们的客户而变化。
- 类图:
通过上面的类图我们可以总结出一下几点:
- 具体算法类 ConcreteStrategyA 和 ConcreteStrategyA 都继承了 Strategy 接口,并且都实现了 algorithm 方法。通过实现接口我们可以很好的实践 开闭原则 ,我们也可以很好的实现扩展
- 类 Client 中有一个 Strategy 变量,通过设置这个变量我们可以很容易的转换我们的算法
- 实现步骤:
- 首先定义一个接口
- 让所有的算法都实现这个接口
- 让客户端持有这个接口
重构思考题
那么通过对Strategy的学习,我们来重构下我们上面的问题:
首先,我们定义一个接口:
Sort.java:
public interface Sort {
Integer[] sort(Integer[] oldOrder);
}
然后,我们定义一系列的算法实现上面定义的接口:
BubbleSort.java:
public class BubbleSort implements Sort {
@Override
public Integer[] sort(Integer[] oldOrder) {
for(int i = 1; i < oldOrder.length; i++) {
for(int j = 0; j < oldOrder.length - i; j++) {
if(oldOrder[j] > oldOrder[j + 1]) {
Integer temp = oldOrder[j];
oldOrder[j] = oldOrder[j + 1];
oldOrder[j + 1] = temp;
}
}
}
return oldOrder;
}
}
QuickSort.java:
public class QuickSort implements Sort {
@Override
public Integer[] sort(Integer[] oldOrder) {
partSort(oldOrder, 0, oldOrder.length - 1);
return oldOrder;
} private void partSort(Integer[] oldOrder, int start, int end) {
if(start < end) {
int middle = swaps(oldOrder, start, end);
partSort(oldOrder, start, middle);
partSort(oldOrder, middle + 1, end);
}
} private int swaps(Integer[] oldOrder, int start, int end) {
Integer temp = oldOrder[start];
for(;start < end;) {
for(;start < end && temp <= oldOrder[end]; end--);
if(start < end) {
oldOrder[start] = oldOrder[end];
start++;
}
for(;start < end && temp > oldOrder[start]; start++);
if(start < end) {
oldOrder[end] = oldOrder[start];
end--;
}
}
oldOrder[start] = temp;
return start;
}
}
最后,我们实现一个算法调用类:
SortAlgorithm.java:
public class SortAlgorithm {
private Sort sort; public void setSort(Sort sort) {
this.sort = sort;
} public Integer[] executeAlgorithm(Integer[] oldOrder) {
return sort.sort(oldOrder);
}
}
测试用例:
Client.java:
import java.util.Random;
import java.util.Arrays; public class Client {
private static int index = 10;
private static int randomMax = 100;
private static Integer[] oldOrder = new Integer[index];
private static Random random = new Random();
static {
for(int i = 0; i < index; i++) {
oldOrder[i] = random.nextInt(randomMax);
}
} public static void main(String... args) {
SortAlgorithm sortAlgorithm = new SortAlgorithm();
Integer[] oldOrder1 = Arrays.copyOf(oldOrder, index);
Integer[] oldOrder2 = Arrays.copyOf(oldOrder, index); sortAlgorithm.setSort(new BubbleSort());
System.out.println(String.format("BubbleSort sort before order:%s", Arrays.asList(oldOrder1).toString()));
long startTime = System.currentTimeMillis();
Integer[] newOrder1 = sortAlgorithm.executeAlgorithm(oldOrder1);
System.out.println(String.format("BubbleSort take time:%s", System.currentTimeMillis() - startTime));
System.out.println(String.format("BubbleSort sort after order:%s", Arrays.asList(newOrder1).toString())); sortAlgorithm.setSort(new QuickSort());
System.out.println(String.format("QuickSort sort before order:%s", Arrays.asList(oldOrder2).toString()));
startTime = System.currentTimeMillis();
Integer[] newOrder2 = sortAlgorithm.executeAlgorithm(oldOrder2);
System.out.println(String.format("QuickSort take time:%s", System.currentTimeMillis() - startTime));
System.out.println(String.format("QuickSort sort after order:%s", Arrays.asList(newOrder2).toString()));
} private static int[] copyOldOrder(int[] oldOrder) {
int[] result = new int[index];
for(int i = 0; i < index; i++) {
result[i] = oldOrder[i];
}
return result;
}
}
上面的代码使用了策略模式,通过使用这个模式我们可以很容易的扩展,现在只要我们实现 Sort 接口就可以扩展我们的排序算法。
[design pattern](1) Strategy的更多相关文章
- Design Pattern - Strategy
Strategy Pattern: The Strategy Pattern defines a family of algorithms,encapsulates each one,and ...
- 说说设计模式~大话目录(Design Pattern)
回到占占推荐博客索引 设计模式(Design pattern)与其它知识不同,它没有华丽的外表,没有吸引人的工具去实现,它是一种心法,一种内功,如果你希望在软件开发领域有一种新的突破,一个质的飞越,那 ...
- 设计模式(Design Pattern)系列之.NET专题
最近,不是特别忙,重新翻了下设计模式,特地在此记录一下.会不定期更新本系列专题文章. 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结. 使用 ...
- [转]Design Pattern Interview Questions - Part 3
State, Stratergy, Visitor Adapter and fly weight design pattern from interview perspective. (I) Can ...
- [转]Design Pattern Interview Questions - Part 1
Factory, Abstract factory, prototype pattern (B) What are design patterns? (A) Can you explain facto ...
- C++ Design Pattern: What is a Design Pattern?
Q: What is a Design Pattern? A: Design Patterns represent solutions to problems what arise when deve ...
- Design Pattern in Simple Examples
Instead of defining what is design pattern lets define what we mean by design and what we mean by pa ...
- java设计模式大全 Design pattern samples in Java(最经典最全的资料)
java设计模式大全 Design pattern samples in Java(最经典最全的资料) 2015年06月19日 13:10:58 阅读数:11100 Design pattern sa ...
- [转]Design Pattern Interview Questions - Part 4
Bridge Pattern, Composite Pattern, Decorator Pattern, Facade Pattern, COR Pattern, Proxy Pattern, te ...
随机推荐
- OSPF与ACL 综合应用
1.企业内网运行OSPF路由协议,区域规划如图所示:2.财务和研发所在的区域不受其他区域链路不稳定性影响:3.R1.R2.R3只允许被IT登录管理:4.YF和CW之间不能互通,但都可以与IT互通:5. ...
- java基础笔记(2)
java中成员变量是有默认初始值的,而局部变量是没有的: 构造方法名和类名相同,没有返回值,即结构如下:public 构造方法名(): 实例化类的本质就是调用了类的构造方法: 如果自定义了构造方法,就 ...
- 数位DP 计划
通常的数位dp可以写成如下形式: [cpp] view plain copy int dfs(int i, int s, bool e) { if (i==-1) return s==target_s ...
- NOIP赛前集训备忘录(含每日总结)(日更?。。。)
NOIP赛前集训备忘录(含每日考试总结) 标签: 有用的东西~(≧▽≦)/~啦啦啦 阅读体验:https://zybuluo.com/Junlier/note/1279194 考试每日总结(这个东西是 ...
- swtich和case语句中,定义变量要加花括号
转自: http://blog.chinaunix.net/uid-27103408-id-3340702.html http://www.xuebuyuan.com/2070170.html swi ...
- Spark出现java.lang.stackoverflowerror的解决方法
正在测试的程序需要多次迭代(400+次),每次迭代有复杂的运算 迭代到100多次的时候报java.lang.stackoverflowerror的错误 解决方法:先checkpoint()再count ...
- Django之F和Q查询
一.F查询 rom django.db.models import F from app01.models import Book Book.objects.update(price=F(" ...
- getchar、putchar、puts、gets
getchar(字符) 输入获取一个字符 putchar(字符) 输出控制台一个字符 scanf()格式化输入 printf() 格式化输出 gets(arr) 输入一个字符串给已经声明的数组ar ...
- Vue框架前言
Vue框架 Vue 框架: 官网 vue框架:渐进式JavaScript框架 vue一个环境:可以只控制页面中一个标签.可以控制一组标签.可以控制整个页面.可以控制整个项目 vue可以根据实际需求,选 ...
- 关于原型链,原来这么简单?—————终结__proto__和prototype的那些事
今天,一个技术群里小朋友提出一个问题: Object.prototype.a = function () { console.log('a') } Function.prototype.b = fun ...