一、模版方法模式简介
按照惯例,先贴一大堆看不懂的概念!
1. 概述
定义一个操作中的算法的骨架,而将步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义算法的某些特定步骤。
2. 模式中的角色
2.1 抽象类(AbstractClass):实现了模板方法,定义了算法的骨架。
2.2 具体类(ConcreteClass):实现抽象类中的抽象方法,已完成完整的算法。
3.模版方法类图
其实我很多时候看完概念都一脸懵逼,我们还是结合例子来理解模版方法模式吧!
二、Demo
现在我们通过一个小的Demo来认识模版方法模式,我们现在要对数组进行从小到大进行排序,可是我们都知道进行排序的算法很多,我们想看下每种算法的效率等等的,那么我们写的每种算法都可能有相同的部分,就好比把排序好的数组输出,这个方法是每个排序类都相同的,为了简洁代码,为了更好的阅读代码,因此我们可以把算法相同的部分抽象出来,写成一个模版,然后每个算法继承这个模版(我们先写好一个骨干的父类,然后子类都继承这个父类)!
看下效果图:
package com.liangdianshui;
import java.util.Date;
public abstract class SortModel {
/**
* 实现排序的方法
*
* @param arrary
*/
protected abstract void sort(int[] array);
/**
* 是否打印排序的时间
*
* (在模版方法类中设置钩子)
*
* @return
*/
public boolean isPrintfTime() {
return false;
}
/**
* 打印排序结果的方法
*
* @param arrary
*/
public void printfResult(int[] array) {
long startTimeMillis = 0;
long endTimeMillis = 0;
if (isPrintfTime()) {
startTimeMillis = System.currentTimeMillis();
}
this.sort(array);
if (isPrintfTime()) {
endTimeMillis = System.currentTimeMillis();
System.out.println("排序所用的时间:" + (endTimeMillis - startTimeMillis) + "ms");
}
System.out.printf("排序的结果为:");
for (int i = 0; i <= array.length - 1; i++) {
System.out.printf("%5s", array[i]);
}
}
/**
* 打印平均值
*
* @param arrary
*/
public void printfAverageValue(int[] array) {
System.out.printf("\n平均值为:");
int sum = 0;
for (int i = 0; i <= array.length - 1; i++) {
sum += array[i];
}
System.out.printf("%5s", sum / array.length);
}
}
然后每个算法的都继承这个父类:
package com.liangdianshui;
public class BubbleSort extends SortModel {
/**
* true 打印时间 false 不打印排序时间
*/
@Override
public boolean isPrintfTime() {
// TODO Auto-generated method stub
return true;
}
@Override
protected void sort(int[] array) {
// TODO Auto-generated method stub
bubbleSort(array);
}
private void bubbleSort(int[] array) {
// TODO Auto-generated method stub
int temp = 0;
for (int i = 0; i < array.length - 1; i++) {
for (int j = 0; j < array.length - 1 - i; j++) {
if (array[j] > array[j + 1]) {
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
}
}
package com.liangdianshui;
public class QuickSort extends SortModel {
/**
* true 打印时间 false 不打印排序时间
*/
@Override
public boolean isPrintfTime() {
// TODO Auto-generated method stub
return true;
}
@Override
protected void sort(int[] array) {
// TODO Auto-generated method stub
quickSort(array);
}
public void quickSort(int[] array) {
if (array.length > 0) { // 查看数组是否为空
quickSort_(array, 0, array.length - 1);
}
}
public int getMiddle(int[] list, int low, int high) {
int tmp = list[low]; // 数组的第一个作为中轴
while (low < high) {
while (low < high && list[high] >= tmp) {
high--;
}
list[low] = list[high]; // 比中轴小的记录移到低端
while (low < high && list[low] <= tmp) {
low++;
}
list[high] = list[low]; // 比中轴大的记录移到高端
}
list[low] = tmp; // 中轴记录到尾
return low; // 返回中轴的位置
}
public void quickSort_(int[] list, int low, int high) {
if (low < high) {
int middle = getMiddle(list, low, high); // 将list数组进行一分为二
quickSort_(list, low, middle - 1); // 对低字表进行递归排序
quickSort_(list, middle + 1, high); // 对高字表进行递归排序
}
}
}
最后就是测试类:
package com.liangdianshui;
import java.util.Random;
public class test {
public static void main(String[] args) {
int[] array1 = randomArray();
System.out.println("冒泡排序");
BubbleSort mBubbleSort = new BubbleSort();
mBubbleSort.printfResult(array1);
mBubbleSort.printfAverageValue(array1);
System.out.println("\n");
System.out.println("快速排序");
int[] array2 = randomArray();
QuickSort mQuickSort = new QuickSort();
mQuickSort.printfResult(array2);
mQuickSort.printfAverageValue(array2);
}
public static int[] randomArray() {
Random random = new Random();
int[] array = new int[400];
for (int i = 0; i < array.length; i++) {
array[i] = random.nextInt(400) + 50;
}
return array;
}
}
运行的结果:
Demo的下载地址:http://download.youkuaiyun.com/detail/two_water/9567834