策略模式
应用场景:comparator
先看需求:
实现一个排序器,要求可以对传入的任意类型数组都进行排序
猫数组排序,狗数组排序,只要有大小关系就可以排序,而这个大小关系是我们人为定义的,如狗的规则可以是饭量小的排前面,猫的规则是体重小的排前面等
先看排序器类:就一个简单的公共排序方法,里边使用的一个简单的选择排序
package org.ali.strategy;
/**
* Author: lury
* Date: 2022-09-04 10:52
*/
public class Sorter {
public static void sort(Comparable[] arr) {
for (int i = 0;i < arr.length - 1;i++) {
int minPos = i;
for (int j = i + 1;j < arr.length;j++) {
minPos = arr[j].CompareTo(arr[minPos]) == -1 ? j : minPos;
}
swap(arr,i,minPos);
}
}
static void swap(Comparable[] arr,int i,int j){
Comparable temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
上面代码可能很多人会有疑问,怎么传的是Comoarable数组?
这就是java设计模式的精华了,要保证代码的通用性,一定要想到接口(多态)。所谓java的设计模式,其实就是接口的各种玩法
我们先看看这个接口
package org.ali.strategy;
/**
* Author: lury
* Date: 2022-09-04 10:51
*/
public interface Comparable {
int CompareTo(Object o);
}
接口是什么?接口描述的是一些事物所具有的共同特征,Comparable即顾名思义是指具有可比较性的一类事物,猫类实现这个接口表示的是猫是可比较的,即可以排序的,狗也如此。只是它们实现不一样,即多态
下面是猫狗类,重点看一下compareTo方法即可
package org.ali.strategy;
/**
* Author: lury
* Date: 2022-09-04 11:00
*/
public class Cat implements Comparable{
int weight,height;
public Cat(int weight, int height) {
this.weight = weight;
this.height = height;
}
@Override
public String toString() {
return "Cat{" +
"weight=" + weight +
", height=" + height +
'}';
}
@Override
public int CompareTo(Object o) { // 重点在这,其他不用看
Cat cat = (Cat) o;
if (this.weight < cat.weight) return -1;
else if (this.weight > cat.weight) return 1;
else return 0;
}
}
package org.ali.strategy;
/**
* Author: lury
* Date: 2022-09-04 11:06
*/
public class Dog implements Comparable {
int foot;// 饭量
@Override
public int CompareTo(Object o) {
Dog d = (Dog)o; // 这里还有些异常,o传进来如果是cat,会报ClassCastException
if (this.foot < d.foot) return -1;
else if (this.foot > d.foot) return 0;
else return 0;
}
@Override
public String toString() {
return "Dog{" +
"foot=" + foot +
'}';
}
public Dog(int foot) {
this.foot = foot;
}
}
下面是测试
public class Main {
public static void main(String[] args) {
Cat[] cats = {new Cat(4,3),new Cat(3,4)};
Dog[] dogs = {new Dog(2),new Dog(4)};
Sorter.sort(cats);
Sorter.sort(dogs);
System.out.println(Arrays.toString(cats));
System.out.println(Arrays.toString(dogs));
}
}
![image-20220904113413541](D:\Download\尚硅谷\msb\designer pattern\img\image-20220904113413541.png)
泛型优化,保证谁用compare方法,就传什么类型参数,比如猫调用,就只能传猫类型,而不会传狗类型,这样就不会出现类转换异常了
package org.ali.strategy;
/**
* Author: lury
* Date: 2022-09-04 10:51
*/
public interface Comparable<T> {
int CompareTo(T o);
}
修改猫狗后的代码
public class Cat implements Comparable<Cat>{
int weight,height;
@Override
public int CompareTo(Cat cat) {
if (this.weight < cat.weight) return -1;
else if (this.weight > cat.weight) return 1;
else return 0;
}
...
}
public class Dog implements Comparable<Dog> {
int foot;// 饭量
@Override
public int CompareTo(Dog d) {
if (this.foot < d.foot) return -1;
else if (this.foot > d.foot) return 0;
else return 0;
}
...
}
搞这么久,其实这还没到策略模式哈,我们实现的Comparable,而策略模式体现在Comparator,不过,别急,
设计模式理论上都差不多的,其最终目的都是帮助我们写出优雅以及便于维护的代码
现在正式进入策略模式
先说以下Comparable接口,确实是帮助我们达到了对任意对象数组实现排序,但是依然是不够灵活的,因为总要
去各个类里实现Comparable接口,耦合度比较高。例如,我要换一种排序规则呢?比如猫之前是按照体重排序,我现在
想要按照身高排序该怎么办?直接改接口实现非常不灵活。说白了,我想要猫的比较大小的策略可以灵活指定,该怎么实现?
这时候策略模式隆重登场啦。我们要知道,在设计的指导思想里边,有一个非常重要的概念,对扩展开放,对修改关闭
Comparator接口
package org.ali.strategy;
/**
* Author: lury
* Date: 2022-09-04 12:44
*/
public interface Comparator<T> {
int compare(T o1,T o2);
}
public class Sorter<T> {
public void sort(T[] arr,Comparator<T> comparator) { // 多传一个比较器
for (int i = 0;i < arr.length - 1;i++) {
int minPos = i;
for (int j = i + 1;j < arr.length;j++) {
minPos = comparator.compare(arr[j],arr[i]) == -1 ? j : minPos;
}
swap(arr,i,minPos);
}
}
}
测试
package org.ali.strategy;
import java.util.Arrays;
/**
* Author: lury
* Date: 2022-09-04 11:08
*/
public class Main {
public static void main(String[] args) {
Cat[] cats = {new Cat(4,7),new Cat(3,4)};
Dog[] dogs = {new Dog(2),new Dog(4)};
new Sorter<Cat>().sort(cats,((o1, o2) ->
o1.height - o2.height < 0 ? -1 : 1
));
System.out.println(Arrays.toString(cats));
}
}
神奇吧?怎么做到的,就是在需要灵活变换的比较方法中,多加一个接口,把接口的实现留白给用户实现
类图
![image-20220904133157807](D:\Download\尚硅谷\msb\designer pattern\img\image-20220904133157807.png)
说白了就是 对策略进行开放拓展,排序的话,就可以有很多种策略
实际怎么运用?去代替if
作者:万能包哥 出处:http://www.cnblogs.com/mybloger/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 如果文中有什么错误,欢迎指出。以免更多的人被误导。 |