一、策略模式:
封装不同的算法,实现客户端调用时可以根据需求,在不修改原算法的情况下,可以很好的切换不同的算法,实现不同的需求;即不同的策略实现不同的功能;比如Comparator比较器接口,由客户端自己去实现不同的compare(Object 1,Object o2)方法,可以由客户端自己去实现对不同对象的排序策略;
需求:对不同的物种进行不同的排序
比如对猫和狗进行排序,对男孩和女孩进行排序如何实现?
非策略模式实现:
1、定义比较器接口
public interface MyComparable<T> {int compareTo(T t1);
}
2、定义需要比较的对象:
/*** 实体类,需要比较的对象必须实现比较的接口,实现比较的算法*/
public class Cat implements MyComparable<Cat> {public Cat(int weight, int height, int food) {this.weight = weight;this.height = height;this.food = food;}private int weight;private int height;private int food;public int getWeight() {return weight;}public void setWeight(int weight) {this.weight = weight;}public int getHeight() {return height;}public void setHeight(int height) {this.height = height;}public int getFood() {return food;}public void setFood(int food) {this.food = food;}@Overridepublic String toString() {return "Cat{" +"weight=" + weight +", height=" + height +", food=" + food +'}';}@Overridepublic int compareTo(Cat t1) {if (this.weight > t1.weight) {return 1;}if (this.weight < t1.weight) {return -1;}return 0;}
}
public class Doggy implements MyComparable<Doggy> {public Doggy(int weight, int height, int food) {this.weight = weight;this.height = height;this.food = food;}private int weight;private int height;private int food;public int getWeight() {return weight;}public void setWeight(int weight) {this.weight = weight;}public int getHeight() {return height;}public void setHeight(int height) {this.height = height;}public int getFood() {return food;}public void setFood(int food) {this.food = food;}@Overridepublic String toString() {return "Doggy{" +"weight=" + weight +", height=" + height +", food=" + food +'}';}@Overridepublic int compareTo(Doggy t1) {if (this.food > t1.food) {return 1;}if (this.food < t1.food) {return -1;}return 0;}
}
3、客户端实现比较算法:
public class SortClient {public static void main(String[] args) {//比较CatCat[] cats = {new Cat(3, 3, 3), new Cat(1, 1, 1), new Cat(5, 5, 5)};for (int i = 0; i < cats.length; i++) {Cat cat1 = cats[i];for (int j = 0; j < cats.length; j++) {Cat cat2 = cats[j];if (cat2.compareTo(cat1) > 0) {//交换下标位置Cat temp = cats[i];cats[i] = cats[j];cats[j] = temp;}}}System.out.println("cat sort:" + cats[0] + cats[1] + cats[2]);}
}
上述案例中,Cat对象是通过比较weight属性来判断大小,Doggy对象是通过比较food属性来比较大小,在实际开发过程中,后续可能会存在这样的需求,比如Cat对象需要通过height属性或者food属性来比较大小,Doggy也需要通过比较weight或者height属性来比较大小,基于设计模式的开闭原则,在不修改原来的代码的情况下,如何实现功能的扩展?
使用策略模式,在原来的代码基础上进行修改:
/*** @param <T> 自定义一个比较器*/
public interface MyComparator<T> {int compare(T t1, T t2);
}
定义一个sort方法,需要传入比较器
public static void sort(Cat[] cats, MyComparator<Cat> myComparator) {for (int i = 0; i < cats.length; i++) {Cat cat1 = cats[i];for (int j = 0; j < cats.length; j++) {Cat cat2 = cats[j];if (myComparator.compare(cat1, cat2) > 0) {//交换下标位置Cat temp = cats[i];cats[i] = cats[j];cats[j] = temp;}}}System.out.println("cat sort:" + cats[0] + cats[1] + cats[2]);}
客户端使用:
//通过策略模式根据不同的属性进行排序sort(cats, new MyComparator<Cat>() {@Overridepublic int compare(Cat t1, Cat t2) {if (t1.getFood() > t2.getFood()) return 1;if (t1.getFood() < t2.getFood()) return -1;return 0;}});//lamda表达式写法sort(cats, (t1, t2) -> {if (t1.getFood() > t2.getFood()) return 1;if (t1.getFood() < t2.getFood()) return -1;return 0;});
Comparator和Comparable
Comparable相当于一个类的自然比较功能,实现该接口的类,能实现对当前类与接口的compareTo方法传进来的参数进行比较;比较的是当前对象与传参进来的对象;
Comparator是一个比较器,策略模式的一种实现,在客户端使用自定义的比较器去实现不同的比较功能;能比较任意的两个对象;java.lang.utils.Comparator里面的比较器也是这样实现的
二、策略模式的其他实现方式:
计算器的实现,通过输入两个不同的值,分别进行+-*%
定义算法接口:
public interface MathOperator {double operate(double o1, double o2);
}
不同的算法实现:
public class AdditionOperator implements MathOperator {@Overridepublic double operate(double o1, double o2) {return o1 + o2;}
}
public class SubtractionOperator implements MathOperator {@Overridepublic double operate(double o1, double o2) {return o1 - o2;}
}
public class MultiplicationOperator implements MathOperator {@Overridepublic double operate(double o1, double o2) {return o1 * o2;}
}
public class DivideOperator implements MathOperator {@Overridepublic double operate(double o1, double o2) {if (o2 == 0) {throw new RuntimeException();}return o1 / o2;}
}
客户端调用不同的实现,不同的算法
public class MathClient {public static void main(String[] args) {double a = 1.89;double b = 3.78;//实现加减乘除,不同的运算operate(new AdditionOperator(), a, b);operate(new SubtractionOperator(), a, b);operate(new MultiplicationOperator(), a, b);operate(new DivideOperator(), a, b);}public static void operate(MathOperator mathOperator, double o1, double o2) {mathOperator.operate(o1, o2);}
}