[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 ...
随机推荐
- Python-自定义函数-参数
一.自定义函数参数 1.种类 (1)位置参数 "x"就是位置参数 #!/usr/bin/env python # -*- coding: utf-8 -*- #author: di ...
- maven中央仓库太慢的解决办法
在.m2目录下创建settings.xml文件,文件内容如下: <?xml version="1.0" encoding="UTF-8"?> < ...
- [转帖]是时候深入了解Linux的系统结构
是时候深入了解Linux的系统结构 http://os.51cto.com/art/201905/596011.htm linux的体系结果 其实自己也知道 linus 做了一个 kernel 大 ...
- 数塔 Medium
Summer is coming! It's time for Iahub and Iahubina to work out, as they both want to look hot at the ...
- http-proxy-middleware
概述 这是设置代理的神器,webpack的devServer.proxy就是使用了非常强大的 http-proxy-middleware 包.Node.js代理很简单. 轻松配置代理中间件进行连接,发 ...
- CQRS框架(nodejs的DDD开发落地框架)初识感想
CQRS是啥?DDD又是啥? 这两个概念其实没什么神秘的,当然此文章中的这两个概念以曾老师的课程为准(关于CQRS和DDD的标准概念,google上已经很多了,不再赘述.) DDD(Domain Dr ...
- CSS 毛玻璃效果
效果图: <!DOCTYPE html> <html lang="en" dir="ltr"> <head> <met ...
- 通过编写串口助手工具学习MFC过程——(二)通过“打开串口”按钮了解基本操作
通过编写串口助手工具学习MFC过程 因为以前也做过几次MFC的编程,每次都是项目完成时,MFC基本操作清楚了,但是过好长时间不再接触MFC的项目,再次做MFC的项目时,又要从头开始熟悉.这次通过做一个 ...
- django部署到linux上不显示.svg图标处理方法
在setting文件的最开始添加如下内容: import mimetypes mimetypes.add_type("image/svg+xml", ".svg" ...
- springmvc,springboot单元测试配置
1. springmvc单元测试配置 <dependency> <groupId>junit</groupId> <artifactId>junit&l ...