选择实现—简单工厂
来源:互联网 发布:小说朗读软件 编辑:程序博客网 时间:2024/04/25 03:50
之前写了好多关于排序算法的文章,基本上都是总结性质的,其实排序算法的研究很细致,但是我的博客都基本上只是给出了大体的思路和Java程序实现,算法写起来比较繁琐,感兴趣的话,自己去研究下吧,我推荐算法导论这本书。
看到这么多的排序算法,如果要将其真正用到Java程序里边的话,未免也太复杂了,因为要为每一种算法在使用之前都要先创建一个实例,然后才能使用,这样就暴露了实现,不符合面向对象的基本要求,因此建立一个工厂类,然后让工厂来负责具体的算法的创建,客户端程序员就不必知道具体的算法了,而且,这样做就可以统一接口。
简单工厂的本质是:封装实现。
需要注意的是简单工厂的重点在于选择,实现是已经做好了的。简单工厂的目的为在于客户端来选择相应的实现,从而使得客户端和实现之间的解耦。这样一来,具体的实现,就不用变动客户端的代码了,这个变化会被简单工厂吸收和屏蔽。
使用我之前写过的算法的例子,可以这样来应用简单工厂模式。
首先,建立一个具体算法的接口,实现面向接口的编程。接口定义如下:
1 package com.alfred.sort; 2 3 public interface SortAlgorithm { 4 /** 5 * 将数组按照升序排序 6 * 7 * @param A 8 * int数组,按升序排列 9 */10 public void sort(int[] A);11 12 /**13 * 将数组按照升序或降序排序14 * 15 * @param A16 * int数组17 * @param isInc18 * 是否升序,true为升序,false为降序19 */20 public void sort(int[] A, boolean isInc);21 }
然后,建立每一个算法的具体实现,每一个算法都要实现这个接口。
1 package com.alfred.sort; 2 3 public class InsertionSort implements SortAlgorithm { 4 5 @Override 6 public void sort(int[] A) { 7 InsertSort(A, true); 8 } 9 10 @Override11 public void sort(int[] A, boolean isInc) {12 InsertSort(A, isInc);13 }14 15 /**16 * 插入排序算法17 * 18 * @param A19 * int数组20 * @param isInc21 * 是否升序,true为升序,false为降序22 */23 private void InsertSort(int[] A, boolean isInc) {24 int len = A.length;25 int key = 0;26 int i = 0;27 for (int j = 1; j < len; j++) {28 key = A[j];29 i = j - 1;30 while (i >= 0 && (isInc ? A[i] > key : A[i] < key)) {31 A[i + 1] = A[i];32 i = i - 1;33 }34 A[i + 1] = key;35 }36 }37 }
1 package com.alfred.sort; 2 3 public class MergeSort implements SortAlgorithm { 4 5 @Override 6 public void sort(int[] A) { 7 mergeSort(A, 0, A.length - 1, true); 8 } 9 10 @Override11 public void sort(int[] A, boolean isInc) {12 mergeSort(A, 0, A.length - 1, isInc);13 }14 15 /**16 * 合并排序17 * @param A18 * int数组19 * @param p20 * 起始位置21 * @param r22 * 终止位置23 * @param isInc24 * 是否升序,true为升序,false为降序25 */26 private void mergeSort(int[] A, int p, int r, boolean isInc) {27 int q = 0;28 if (p < r) {29 q = (p + r) / 2;30 mergeSort(A, p, q, isInc);31 mergeSort(A, q + 1, r, isInc);32 merge(A, p, q, r, isInc);33 }34 }35 36 /**37 * 合并两个排好的序列38 * @param A39 * int数组40 * @param p41 * 起始位置42 * @param q43 * 中间位置44 * @param r45 * 终止位置46 * @param isInc47 * isInc 是否升序,true为升序,false为降序48 */49 private void merge(int[] A, int p, int q, int r, boolean isInc) {50 int nLeft = q - p + 1;51 int nRight = r - q;52 int[] left = new int[nLeft];53 int[] right = new int[nRight];54 int i = 0, j = 0, k = 0;55 for (i = 0; i < nLeft; i++) {56 left[i] = A[p + i];57 }58 for (j = 0; j < nRight; j++) {59 right[j] = A[q + j + 1];60 }61 i = 0;62 j = 0;63 for (k = p; k <= r; k++) {64 if (isInc ^ (left[i] <= right[j])) {65 A[k] = right[j];66 j++;67 } else {68 A[k] = left[i];69 i++;70 }71 72 if (i == nLeft) {73 k++;74 for (; j < nRight; j++) {75 A[k] = right[j];76 k++;77 }78 }79 if (j == nRight) {80 k++;81 for (; i < nLeft; i++) {82 A[k] = left[i];83 k++;84 }85 }86 }87 }88 }
1 package com.alfred.sort; 2 3 public class HeapSort implements SortAlgorithm { 4 5 private IntArray A = null; 6 7 public HeapSort() { 8 A = new IntArray(); 9 } 10 11 private class IntArray { 12 public int[] aArray = null; 13 public int heapSize = 0; 14 } 15 16 @Override 17 public void sort(int[] A) { 18 maxHeapSort(A); 19 } 20 21 @Override 22 public void sort(int[] A, boolean isInc) { 23 if (isInc) { 24 maxHeapSort(A); 25 } else { 26 minHeapSort(A); 27 } 28 } 29 30 /** 31 * 最大堆排序,升序 32 * 33 * @param A 34 * int数组 35 */ 36 private void maxHeapSort(int[] A) { 37 this.A.aArray = A; 38 this.A.heapSize = A.length; 39 buildMaxHeap(this.A); 40 for (int i = A.length; i >= 2; i--) { 41 exchange(1, i); 42 this.A.heapSize = this.A.heapSize - 1; 43 maxHeapify(this.A, 1); 44 } 45 } 46 47 /** 48 * 最小堆排序,降序 49 * 50 * @param A 51 * int数组 52 */ 53 private void minHeapSort(int[] A) { 54 this.A.aArray = A; 55 this.A.heapSize = A.length; 56 buildMinHeap(this.A); 57 for (int i = A.length; i >= 2; i--) { 58 exchange(1, i); 59 this.A.heapSize = this.A.heapSize - 1; 60 minHeapify(this.A, 1); 61 } 62 } 63 64 /** 65 * 使得以index为根的子树成为最大堆 66 * 67 * @param A 68 * int数组 69 * @param index 70 * 以index为根,从1开始 71 */ 72 private void maxHeapify(IntArray A, int index) { 73 while (index < A.heapSize / 2 + 1) { 74 int left = left(index); 75 int right = right(index); 76 int largest = 0; 77 if (left <= A.heapSize && A.aArray[left - 1] > A.aArray[index - 1]) { 78 largest = left; 79 } else { 80 largest = index; 81 } 82 if (right <= A.heapSize 83 && A.aArray[right - 1] > A.aArray[largest - 1]) { 84 largest = right; 85 } 86 if (index != largest) { 87 exchange(index, largest); 88 index = largest; 89 } else { 90 index = A.heapSize / 2 + 1; 91 } 92 } 93 } 94 95 /** 96 * 使得以index为根的子树成为最小堆 97 * 98 * @param A 99 * int数组100 * @param index101 * 以index为根,从1开始102 */103 private void minHeapify(IntArray A, int index) {104 while (index < A.heapSize / 2 + 1) {105 int left = left(index);106 int right = right(index);107 int smallest = 0;108 if (left <= A.heapSize && A.aArray[left - 1] < A.aArray[index - 1]) {109 smallest = left;110 } else {111 smallest = index;112 }113 if (right <= A.heapSize114 && A.aArray[right - 1] < A.aArray[smallest - 1]) {115 smallest = right;116 }117 if (index != smallest) {118 exchange(index, smallest);119 index = smallest;120 } else {121 index = A.heapSize / 2 + 1;122 }123 }124 }125 126 /**127 * 建最大堆128 * 129 * @param A130 * int数组131 */132 private void buildMaxHeap(IntArray A) {133 for (int i = A.aArray.length / 2; i >= 1; i--) {134 maxHeapify(A, i);135 }136 }137 138 /**139 * 建最小堆140 * 141 * @param A142 * int数组143 */144 private void buildMinHeap(IntArray A) {145 for (int i = A.aArray.length / 2; i >= 1; i--) {146 minHeapify(A, i);147 }148 }149 150 private int left(int index) {151 return 2 * index;152 }153 154 private int right(int index) {155 return 2 * index + 1;156 }157 158 private void exchange(int i, int j) {159 int temp = A.aArray[i - 1];160 A.aArray[i - 1] = A.aArray[j - 1];161 A.aArray[j - 1] = temp;162 }163 164 }
1 package com.alfred.sort; 2 3 import java.util.Random; 4 5 public class QuickSort implements SortAlgorithm { 6 7 private Random rand = null; 8 9 public QuickSort() {10 rand = new Random();11 }12 13 @Override14 public void sort(int[] A) {15 randomizedQuickSort(A, 1, A.length, true);16 }17 18 @Override19 public void sort(int[] A, boolean isInc) {20 randomizedQuickSort(A, 1, A.length, isInc);21 }22 23 /**24 * 随机化的快速排序25 * @param A 要排序的int数组26 * @param p 起始位置27 * @param r 终止位置28 * @param isInc 是否升序,true为升序,false为降序29 */30 private void randomizedQuickSort(int[] A, int p, int r, boolean isInc) {31 if (p < r) {32 int q = randomizedPartition(A, p, r, isInc);33 randomizedQuickSort(A, p, q - 1, isInc);34 randomizedQuickSort(A, q + 1, r, isInc);35 }36 }37 38 /**39 * 随机化的对数组的划分40 * @param A 要划分的int数组41 * @param p 起始位置42 * @param r 终止位置43 * @param isInc 是否升序,true为升序,false为降序44 * @return 划分数组的下标45 */46 private int randomizedPartition(int[] A, int p, int r, boolean isInc) {47 int i = rand.nextInt(r - p);48 exchange(A, r, i + p);49 return partition(A, p, r, isInc);50 }51 52 /**53 * 对数组进行划分54 * @param A 要划分的int数组55 * @param p 起始位置56 * @param r 终止位置57 * @param isInc 是否升序,true为升序,false为降序58 * @return 划分数组的下标59 */60 private int partition(int[] A, int p, int r, boolean isInc) {61 int x = A[r - 1];62 int i = p - 1;63 for (int j = p; j <= r - 1; j++) {64 if (isInc ? A[j - 1] <= x : A[j - 1] >= x) {65 i++;66 exchange(A, i, j);67 }68 }69 exchange(A, i + 1, r);70 return i + 1;71 }72 73 private void exchange(int[] A, int i, int j) {74 int temp = A[i - 1];75 A[i - 1] = A[j - 1];76 A[j - 1] = temp;77 }78 }
接下来,建立一个工厂类来为客户端选择具体的算法实现。
1 package com.alfred.sort; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.util.Properties; 6 7 public class SortFactory { 8 9 public static SortAlgorithm getSortAlgorithm(String type) {10 11 Properties prop = new Properties();12 InputStream in = null;13 14 try{15 in = SortFactory.class.getResourceAsStream("FactoryConfig.properties");16 prop.load(in);17 }catch(IOException e){18 System.out.println("装载配置文件出错,具体的堆栈信息如下:");19 e.printStackTrace();20 }finally{21 try{22 in.close();23 }catch(IOException e){24 e.printStackTrace();25 }26 }27 28 SortAlgorithm sortAlgorithm = null;29 try{30 sortAlgorithm = (SortAlgorithm)Class.forName(prop.getProperty(type)).newInstance();31 }catch(InstantiationException e){32 e.printStackTrace();33 }catch(IllegalAccessException e){34 e.printStackTrace();35 }catch(ClassNotFoundException e){36 e.printStackTrace();37 }38 return sortAlgorithm;39 }40 41 private SortFactory() {42 43 }44 }
其中反射用的配置文件如下:
1 insert_sort = com.alfred.sort.InsertionSort2 merge_sort = com.alfred.sort.MergeSort3 heap_sort = com.alfred.sort.HeapSort4 quick_sort = com.alfred.sort.QuickSort
当然,还有之前简化的打印类:
1 package com.alfred.sort; 2 3 public class Print { 4 public static void print() { 5 System.out.println(); 6 } 7 8 public static void print(boolean x) { 9 System.out.println(x);10 }11 12 public static void print(char x) {13 System.out.println(x);14 }15 16 public static void print(char[] x) {17 System.out.println(x);18 }19 20 public static void print(double x) {21 System.out.println(x);22 }23 24 public static void print(float x) {25 System.out.println(x);26 }27 28 public static void print(int x) {29 System.out.println(x);30 }31 32 public static void print(long x) {33 System.out.println(x);34 }35 36 public static void print(Object x) {37 System.out.println(x);38 }39 40 public static void print(String x) {41 System.out.println(x);42 }43 44 private Print() {45 46 }47 }
还有定义算法名称的常量类:
1 package com.alfred.sort; 2 3 public class AlgorithmConstants { 4 5 public static final String INSERT_SORT = "insert_sort"; 6 public static final String MERGE_SORT = "merge_sort"; 7 public static final String HEAP_SORT = "heap_sort"; 8 public static final String QUICK_SORT = "quick_sort"; 9 10 private AlgorithmConstants() {11 12 }13 }
最后,来写一个测试类来测试一下吧!
1 package com.alfred.sort; 2 3 import static com.alfred.sort.Print.print; 4 5 public class SortMain { 6 7 public static void main(String[] args) { 8 9 int[] A = new int[] { 23, 45, 36, 78, 45, 16, 59, 62, 569 };10 int[] aCopy = null;11 print("原始数组:");12 printIntArray(A);13 14 /**********************15 * 插入排序16 *********************/17 SortAlgorithm insertSort = SortFactory18 .getSortAlgorithm(AlgorithmConstants.INSERT_SORT);19 print("插入排序,升序排列:");20 aCopy = A.clone();21 insertSort.sort(aCopy);22 printIntArray(aCopy);23 print("插入排序,降序排列:");24 aCopy = A.clone();25 insertSort.sort(aCopy, false);26 printIntArray(aCopy);27 28 /**********************29 * 合并排序30 *********************/31 SortAlgorithm mergeSort = SortFactory32 .getSortAlgorithm(AlgorithmConstants.MERGE_SORT);33 print("合并排序,升序排列:");34 aCopy = A.clone();35 mergeSort.sort(aCopy);36 printIntArray(aCopy);37 print("合并排序,降序排列:");38 aCopy = A.clone();39 mergeSort.sort(aCopy, false);40 printIntArray(aCopy);41 42 /**********************43 * 堆排序44 *********************/45 SortAlgorithm heapSort = SortFactory46 .getSortAlgorithm(AlgorithmConstants.HEAP_SORT);47 print("最大堆排序,升序排列:");48 aCopy = A.clone();49 heapSort.sort(aCopy);50 printIntArray(aCopy);51 print("最小堆排序,降序排列:");52 aCopy = A.clone();53 heapSort.sort(aCopy, false);54 printIntArray(aCopy);55 56 /**********************57 * 快速排序58 *********************/59 SortAlgorithm quickSort = SortFactory60 .getSortAlgorithm(AlgorithmConstants.QUICK_SORT);61 print("快速排序,升序排列:");62 aCopy = A.clone();63 quickSort.sort(aCopy);64 printIntArray(aCopy);65 print("快速排序,降序排列:");66 aCopy = A.clone();67 quickSort.sort(aCopy, false);68 printIntArray(aCopy);69 70 }71 72 private static void printIntArray(int[] A){73 int row = A.length / 10 + 1;74 int index = 0;75 for(int i = 0; i < row; i++){76 for(int j = 0; j < 10; j++){77 index = i * 10 + j;78 if(index >= A.length){79 break;80 }else{81 boolean x = (index + 1) % 10 == 0 || index == A.length - 1;82 if(x){83 System.out.print(A[index]);84 }else{85 System.out.print(A[index] + ",");86 }87 }88 }89 }90 print();91 }92 }
输出为:
原始数组:
23,45,36,78,45,16,59,62,569
插入排序,升序排列:
16,23,36,45,45,59,62,78,569
插入排序,降序排列:
569,78,62,59,45,45,36,23,16
合并排序,升序排列:
16,23,36,45,45,59,62,78,569
合并排序,降序排列:
569,78,62,59,45,45,36,23,16
最大堆排序,升序排列:
16,23,36,45,45,59,62,78,569
最小堆排序,降序排列:
569,78,62,59,45,45,36,23,16
快速排序,升序排列:
16,23,36,45,45,59,62,78,569
快速排序,降序排列:
569,78,62,59,45,45,36,23,16
从这个结果可以看出,所有的算法都能完成排序的工作,而且用了简单工厂模式之后,客户端程序就再也不需要知道具体的排序算法的实现了。
- 选择实现—简单工厂
- 运用简单工厂实现登陆权限的选择
- c#实现简单工厂—数据库连接
- 实现简单工厂模式
- 简单工厂的实现
- 简单实现抽象工厂
- 工厂模式简单实现
- 简单实现工厂模式
- 简单工厂~工厂模式--Java实现
- 选择排序 简单实现
- 选择排序简单实现
- 简单的数据库连接工厂实现
- 简单工厂之Delphi实现
- 阅简单工厂实现心得
- 简单工厂模式的实现
- 简单工厂之Delphi实现
- 简单工厂模式的实现
- 简单的工厂模式实现
- Project——通过Http发送请求
- 后台server常用技术学习总结
- u-boot-2012.04 编译和skyeye仿真flash:***failed***问题
- 修改活动窗口标题栏的样式和标题栏字体
- thunderbird 使用命令行发邮件
- 选择实现—简单工厂
- Android安装程序时显示timeout的解决办法
- VC 实现 自绘 窗体 标题栏 非客户区
- Project——手机号码归属地查询
- Windows上USB设备检测
- Ubuntu下Gcc编译流程及方法
- 十二月工作总结
- android中用jsonObject解析json数据
- equals与“==”之惑