所有源码的git地址https://gitee.com/0x208_jackson/design-patterns
1、设计模式该怎么用
当我们项目中出现了多个if……else的时候就可以选择使用策略模式,策略模式就是做同一件事件的不同的方法,设计模式说到底就是java多态的灵活运用。设计项目时我们一般要遵循开闭原则,即关闭修改,打开扩展,也就是说尽量别去修改现有的代码,而是对其进行扩展,这就要求我们在设计的时候需要考虑到可以进行灵活的扩展。
2、策略模式-比较动物大小
2.1、根据体重比较
我们现在有一只猫,根据体重比较猫的大小,代码如下:
猫的实体对象
package com.xin.demo.strategy;
import java.io.Serializable;
public class Cat implements Serializable {
private final int weight;
private final int height;
public int compareToHeight(Cat cat) {
return this.weight - cat.weight;
}
public Cat(int weight, int height) {
this.weight = weight;
this.height = height;
}
@Override
public String toString() {
return "Cat{" +
"weight=" + weight +
", height=" + height +
'}';
}
}
排序:
package com.xin.demo.strategy;
public class Sort {
// 此处通过 采用选择排序进行排序
public static void selectionSort(Cat[] arr) {
if (arr == null || arr.length < 2) {
return;
}
for (int i = 0; i < arr.length - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < arr.length; j++) {
// 此处是重点需要注意,注意看调用的方法名
// 此处需要根据 不同的比较方式去调用不同的方法,也就是会产生多个if……else
minIndex = arr[j].compareToHeight(arr[minIndex]) < 0 ? j : minIndex;
}
swap(arr, i, minIndex);
}
}
public static void swap(Cat[] arr, int i, int j) {
Cat tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
执行:
package com.xin.demo.strategy;
import java.util.Arrays;
public class OperatorMain {
public static void main(String[] args) {
Cat[] a = {new Cat(23, 2),
new Cat(14, 11),
new Cat(5, 7),
new Cat(1, 1)};
Sort.selectionSort(a);
System.out.println(Arrays.toString(a));
}
}
2.2、根据身高比较
现在我希望根据猫的身高比较猫的大小,按照常规写法,我们需要<font color='red'>在 Cat
</font>对象里面在实现一个方法.
package com.xin.demo.strategy;
import java.io.Serializable;
public class Cat implements Serializable {
private final int weight;
private final int height;
public int compareToHeight(Cat cat) {
return this.weight - cat.weight;
}
// 此处为新增加的 根据体重进行比较的方法
public int compareToWeight(Cat cat) {
return this.weight - cat.weight;
}
public Cat(int weight, int height) {
this.weight = weight;
this.height = height;
}
@Override
public String toString() {
return "Cat{" +
"weight=" + weight +
", height=" + height +
'}';
}
}
修改排序的调用方法
package com.xin.demo.strategy;
public class Sort {
// 此处通过 采用选择排序进行排序
public static void selectionSort(Cat[] arr) {
if (arr == null || arr.length < 2) {
return;
}
for (int i = 0; i < arr.length - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < arr.length; j++) {
// 注意此处改成了 调用体重的方法
// 此处需要根据 不同的比较方式去调用不同的方法,也就是会产生多个if……else
minIndex = arr[j].compareToWeight(arr[minIndex]) < 0 ? j : minIndex;
}
swap(arr, i, minIndex);
}
}
public static void swap(Cat[] arr, int i, int j) {
Cat tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
2.3、根据策略模式
以上两种情况我们发现,如果在做同一件猫的大小的比较,根据不同的方式去做的时候我们需要写很多冗余的代码,且不利于扩展,如在增加一种比较方式的时候,我们需要继续进行方法的迭代,且排序方法需要在增加或者重写,此处策略主要针对的是排序部分。
既然是同一件事情,不同的方式去做,那么我们可以定义一个比较器接口,通过不同的实现来完成。
首先定义一个接口:
package com.xin.demo.strategy;
public interface Comparator<T> {
// 比较器
int compare(T o1, T o2);
}
对应的实现:
体重:
package com.xin.demo.strategy;
public class CatCompareToHeight implements Comparator<Cat> {
@Override
public int compare(Cat o1, Cat o2) {
return o1.height - o2.height;
}
}
身高:
package com.xin.demo.strategy;
public class CatCompareToWeight implements Comparator<Cat> {
@Override
public int compare(Cat o1, Cat o2) {
return o1.weight - o2.weight;
}
}
排序方法:
package com.xin.demo.strategy;
public class StrategySort<T> {
// 此处通过 采用选择排序进行排序
public void selectionSort(T[] arr, Comparator<T> comparator) {
if (arr == null || arr.length < 2) {
return;
}
for (int i = 0; i < arr.length - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < arr.length; j++) {
// 重点
minIndex = comparator.compare(arr[j], arr[minIndex]) < 0 ? j : minIndex;
}
swap(arr, i, minIndex);
}
}
public void swap(T[] arr, int i, int j) {
T tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
执行:
package com.xin.demo.strategy;
import java.util.Arrays;
public class OperatorMain {
public static void main(String[] args) {
Cat[] cat = {new Cat(3, 4),
new Cat(14, 11),
new Cat(5, 17),
new Cat(1, 2)};
// 普通写法
Sort.selectionSort(cat);
System.out.println(Arrays.toString(cat));
// 策略模式写法
StrategySort<Cat> strategySort = new StrategySort<>();
// 传进去需要比较的对象,以及对应的策略,也就是对应的比较方式
// 根据身高比较
strategySort.selectionSort(cat, new CatCompareToHeight());
System.out.println("根据height排序:"+Arrays.toString(cat));
//根据体重进行比较
strategySort.selectionSort(cat, new CatCompareToWeight());
System.out.println("根据weight排序:"+Arrays.toString(cat));
}
}
2.4、可以比较任何动物的大小
package com.xin.demo.strategy;
import java.util.Arrays;
public class OperatorMain {
public static void main(String[] args) {
// 现在我们不仅可以比较猫的大小,还可以比较任何一个动物的大小
// lambda 表达式写法
StrategySort<Dog> dogStrategySort = new StrategySort<>();
Dog[] dogs = {new Dog(3, 9),
new Dog(1, 11),
new Dog(4, 1),
new Dog(2, 2)};
dogStrategySort.selectionSort(dogs, new Comparator<Dog>() {
@Override
public int compare(Dog o1, Dog o2) {
return o1.height - o2.height;
}
});
System.out.println(Arrays.toString(dogs));
}
}
网友评论