策略模式
策略模式
- 策略模式封装的是做一件事的不同方式,下面通过排序方式为例讲解这个问题。
package StrategyPattern;
import java.util.Arrays;
class Sorter {
static void swap(int[] vec, int i, int j){
int tmp = vec[i];
vec[i] = vec[j];
vec[j] = tmp;
}
public static void sort(int[] vec){
for(int i = 0; i < vec.length; i++){
int index = i;
for(int j = i+1; j < vec.length; j++){
index = vec[index] > vec[j] ? j : index;
}
swap(vec, index, i);
}
}
}
public class Main {
public static void main(String[] args) {
int[] a = {9, 2, 3, 5, 7, 1, 4};
Sorter sorter = new Sorter();
sorter.sort(a);
System.out.println(Arrays.toString(a));
}
}
结果
[1, 2, 3, 4, 5, 7, 9]
如果现在要做double,float类型的排序,或者自定义的类型该如何做呢,很自然的想到,重载上面的排序方法,但这样会产生很多冗余代码,开发效率提下且扩展性不好。那么如何解决这个问题呢。这个时候可以考虑使用Java中的Comparable接口
- sort()形参的类型定义为Comparable[] vec,Comparable接口中定义了compareTo比较方法,自定义类实现Compare接口,重载compareTo方法。
package StrategyPattern;
import java.util.Arrays;
class Cat implements Comparable<Cat> {
int weight;
int height;
public Cat(int weight, int height){
this.weight = weight;
this.height = height;
}
public int compareTo(Cat c){
if(this.weight < c.weight)
return -1;
else if(this.weight > c.weight)
return 1;
else
return 0;
}
@Override
public String toString() {
return "Cat{" +
"weight=" + weight +
", height=" + height +
'}';
}
}
class Sorter {
static void swap(Comparable[] vec, int i, int j){
Comparable tmp = vec[i];
vec[i] = vec[j];
vec[j] = tmp;
}
public static void sort(Comparable[] vec){
for(int i = 0; i < vec.length; i++){
int index = i;
for(int j = i+1; j < vec.length; j++){
index = vec[j].compareTo(vec[index]) == -1? j : index;
}
swap(vec, index, i);
}
}
}
public class Main {
public static void main(String[] args) {
Cat[] a = {new Cat(1,3), new Cat(3,5), new Cat(5,2)};
Sorter sorter = new Sorter();
sorter.sort(a);
System.out.println(Arrays.toString(a));
}
}
结果
[Cat{weight=1, height=1}, Cat{weight=3, height=3}, Cat{weight=5, height=5}]
现在通过实现Comparable接口及泛型编程解决了需要对每个类别重载的问题,但是假如换了一种比较方法呢,不按猫的体重进行排序,改成按猫的身高进行排序呢。那么就要重写compareTo方法,这样就破坏了原来的代码。那么如何解决呢
策略模式的引出
- 可以通过Java中的Comparator比较器解决上述问题,可以通过实现Comparator接口自定义比较方法,不用修改类内比较方法。
- 这种封装做一件事情的不同方式就成为策略模式。
package StrategyPattern;
import java.util.Arrays;
import java.util.Comparator;
class Cat implements Comparable<Cat> {
int weight;
int height;
public Cat(int weight, int height){
this.weight = weight;
this.height = height;
}
public int compareTo(Cat c){
if(this.weight < c.weight)
return -1;
else if(this.weight > c.weight)
return 1;
else
return 0;
}
@Override
public String toString() {
return "Cat{" +
"weight=" + weight +
", height=" + height +
'}';
}
}
class Sorter<T> {
void swap(T[] vec, int i, int j){
T tmp = vec[i];
vec[i] = vec[j];
vec[j] = tmp;
}
public void sort(T[] vec, Comparator<T> comparator){
for(int i = 0; i < vec.length; i++){
int index = i;
for(int j = i+1; j < vec.length; j++){
index = comparator.compare(vec[j],vec[index]) == -1? j : index;
}
swap(vec, index, i);
}
}
}
class CatComparator implements Comparator<Cat>{
@Override
public int compare(Cat o1, Cat o2) {
if (o1.height < o2.height)
return -1;
else if(o1.height > o2.height)
return 1;
else
return 0;
}
}
public class Main {
public static void main(String[] args) {
Cat[] a = {new Cat(1,3), new Cat(3,5), new Cat(5,2)};
Sorter<Cat> sorter = new Sorter<>();
sorter.sort(a, new CatComparator());
System.out.println(Arrays.toString(a));
}
}
结果
[Cat{weight=5, height=2}, Cat{weight=1, height=3}, Cat{weight=3, height=5}]