引言

最近,在学习设计模式相关的知识。本博客主要想讲一讲策略模式,这也是我学习的第一个模式。写下这篇博客,主要想记录下个人的一点理解,也是想通过写博客的方式来加深对与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

  • 定义: 定义一系列的算法,将每一个算法封装起来,并且让这些封装的算法之间可以相互替换。该模式可以使算法独立于使用它们的客户而变化。
  • 类图:

通过上面的类图我们可以总结出一下几点:

  1. 具体算法类 ConcreteStrategyA 和 ConcreteStrategyA 都继承了 Strategy 接口,并且都实现了 algorithm 方法。通过实现接口我们可以很好的实践 开闭原则 ,我们也可以很好的实现扩展
  2. 类 Client 中有一个 Strategy 变量,通过设置这个变量我们可以很容易的转换我们的算法
  • 实现步骤:
  1. 首先定义一个接口
  2. 让所有的算法都实现这个接口
  3. 让客户端持有这个接口

重构思考题

那么通过对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的更多相关文章

  1. Design Pattern - Strategy

    Strategy Pattern:     The Strategy Pattern defines a family of algorithms,encapsulates each one,and ...

  2. 说说设计模式~大话目录(Design Pattern)

    回到占占推荐博客索引 设计模式(Design pattern)与其它知识不同,它没有华丽的外表,没有吸引人的工具去实现,它是一种心法,一种内功,如果你希望在软件开发领域有一种新的突破,一个质的飞越,那 ...

  3. 设计模式(Design Pattern)系列之.NET专题

    最近,不是特别忙,重新翻了下设计模式,特地在此记录一下.会不定期更新本系列专题文章. 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结. 使用 ...

  4. [转]Design Pattern Interview Questions - Part 3

    State, Stratergy, Visitor Adapter and fly weight design pattern from interview perspective. (I) Can ...

  5. [转]Design Pattern Interview Questions - Part 1

    Factory, Abstract factory, prototype pattern (B) What are design patterns? (A) Can you explain facto ...

  6. 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 ...

  7. 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 ...

  8. java设计模式大全 Design pattern samples in Java(最经典最全的资料)

    java设计模式大全 Design pattern samples in Java(最经典最全的资料) 2015年06月19日 13:10:58 阅读数:11100 Design pattern sa ...

  9. [转]Design Pattern Interview Questions - Part 4

    Bridge Pattern, Composite Pattern, Decorator Pattern, Facade Pattern, COR Pattern, Proxy Pattern, te ...

随机推荐

  1. 最全的DevOps自动化工具集合

    版本控制&协作开发:GitHub.GitLab.BitBucket.SubVersion.Coding.Bazaar 自动化构建和测试:Apache Ant.Maven .Selenium.P ...

  2. Java——HashMap使用Demo

    package map; import java.util.Collection; import java.util.HashMap; import java.util.Set; public cla ...

  3. asp.net获取访问者ip地址的函数

    /// <summary> /// 获取IP地址 /// </summary> public static string IPAddress { get { string us ...

  4. tensorflow学习笔记七----------卷积神经网络

    卷积神经网络比神经网络稍微复杂一些,因为其多了一个卷积层(convolutional layer)和池化层(pooling layer). 使用mnist数据集,n个数据,每个数据的像素为28*28* ...

  5. Python 入门之流程控制语句

    Python 入门之流程控制语句 1.if判断 (1) 单 if if –-如果 if 条件: 缩进 结果 (官方推荐4个空格,或者一个tab 不能空格和tab混合使用) money = 10 pri ...

  6. ASP.NET的面包屑导航控件、树形导航控件、菜单控件

    原文:http://blog.csdn.net/pan_junbiao/article/details/8579293 ASP.NET的面包屑导航控件.树形导航控件.菜单控件. 1. 面包屑导航控件— ...

  7. spring controller 方法测试

    controller 测试 不使用其他api接口测试工具 一般而言,我们写好一个模块后,会对其进行单元测试,再集成到现有的系统中. 但是呢~针对Controller.Service.Dao三层来说,我 ...

  8. Restful,SAOP,SOA,RPC的基础理解

    什么是Restful restful是一种架构设计风格,提供了设计原则和约束条件,而不是架构.而满足这些约束条件和原则的应用程序或设计就是 RESTful架构或服务. 主要的设计原则: 资源与URI ...

  9. 将Medium中的博客导出成markdown

    Medium(https://medium.com)(需要翻墙访问)是国外非常知名的一个博客平台.上面经常有很多知名的技术大牛在上面发布博客,现在一般国内的搬运的技术文章大多数都是来自于这个平台. M ...

  10. PowerEdge T630服务器安装机器学习环境(Ubuntu18.04、Nvidia 1080Ti驱动、CUDA及CUDNN安装)

    安装步骤 在开始安装之前,我要说明一下,这个Ubuntu18.04系统的安装,使用的连接线(就是服务器和电脑显示器的连接线)必须两头都是VGA连接线,不能使用VGA转HDMI连接线,也不能用DVI转D ...