Java设计模式之策略模式

}

}

复制代码

这个排序工具类有一个问题,就是仅支持int数组,如果需要被处理的是Object对象等类型就不行了,所以让我们来一步一步用策略模式来改造一下。

首先新建两个用于测试的类CatDog

package com.cc.strategy;

public class Cat {

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 +

‘}’;

}

}

复制代码

package com.cc.strategy;

public class Dog {

int food;

public Dog(int food) {

this.food = food;

}

@Override

public String toString() {

return “Dog{” +

“food=” + food +

‘}’;

}

}

复制代码

其中Cat有两个属性,重量weight和高度height,Dog有一个饭量food。

首先我们希望Sorter类可以做到,将Cat数组根据weight排序,那么我们可以这样写:

新建一个比较的实现类Comparable(我知道Java已经有这个实现类了,但是为了加深理解,让我们手撸一个吧):

package com.cc.strategy;

public interface Comparable {

int compareTo(T o);

}

复制代码

其中泛型T可能会有疑惑,后面会提到,

为了支持Sorter排序,Cat需要实现这个Comparable类,修改后如下:

package com.cc.strategy2;

// 上面提到的泛型可以在此处指定…

public class Cat implements Comparable {

int weight, height;

public Cat(int weight, int height) {

this.weight = weight;

this.height = height;

}

/**

  • …然后本来是T o格式,使用了泛型并且在类上指定之后可以在实现函数中直接用Cat c的方式指定

  • 这样其实是自动做了一层转换:Object o => Cat c

  • 如果不用泛型,就要这样多写一行:

  • Cat c = (Cat)o;

*/

@Override

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 +

‘}’;

}

}

复制代码

Sorter排序类也要修改,从原来只接受int[]变成Comparable[],即所有实现了Comparable的对象:

package com.cc.strategy2;

public class Sorter {

public void sort(Comparable[] arr) {

for (int i = 0; i < arr.length; 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);

}

}

private void swap(Comparable[] arr, int i, int minPos) {

Comparable temp = arr[i];

arr[i] = arr[minPos];

arr[minPos] = temp;

}

}

复制代码

测试一下;

package com.cc.strategy;

import java.util.Arrays;

public class Main {

public static void main(String[] args) {

Cat[] c = {new Cat(3, 3), new Cat(5, 5), new Cat(1, 1)};

Sorter sorter = new Sorter();

sorter.sort©;

System.out.println(Arrays.toString©);

}

}

复制代码

结果:

[Cat{weight=1, height=1}, Cat{weight=3, height=3}, Cat{weight=5, height=5}]

复制代码

Cat类的排序已经完成了,当我们想对Dog也进行排序的话,参照Cat类即可:

package com.cc.strategy;

public class Dog implements Comparable {

int food;

public Dog(int food) {

this.food = food;

}

@Override

public int compareTo(Dog d) {

if (this.food < d.food) {

return -1;

} else if (this.food > d.food) {

return 1;

} else {

return 0;

}

}

@Override

public String toString() {

return “Dog{” +

“food=” + food +

‘}’;

}

}

复制代码

现在还有一个问题,Cat的排序,我们是在Cat类的实现函数compareTo()中根据weight来排的,Cat有两个属性weight和height,当我们想让Cat变成按照height排序的话怎么办呢?修改实现函数compareTo()是肯定不行的,这样一点也不灵活,现在终于轮到策略模式出场了,是的,前面的都不是策略模式,只是铺垫。

让我们来新建一个比较实现类Comparator:

package com.cc.strategy;

public interface Comparator {

int comare(T o1, T o2);

}

复制代码

现在可以开始疑惑了,这个Comparator和刚刚的Comparable有什么区别呢?

答:在Java中,Comparable是排序接口,如果一个类实现了Comparable接口,表示该类支持排序,就像我们在Sorter中实现的,实现类Comparable的对象通过compareTo()方法进行排序,返回1,-1或者0;

而Comparator是比较接口,通常是用于一种比较方法的实现,听到这里可能还是不理解,没关系我们接着看。


在刚刚,Cat是通过weight排序的,为了让Cat能够灵活一些,既可以根据weight排序,也可以根据height排序,我们新建两个比较类:

package com.cc.strategy;

public class CatHeightComparator implements Comparator {

@Override

public int comare(Cat o1, Cat o2) {

if (o1.height < o2.height) {

return 1;

} else if (o1.height > o2.height) {

return -1;

} else {

return 0;

}

}

}

复制代码

package com.cc.strategy;

public class CatWeightComparator implements Comparator {

@Override

public int comare(Cat o1, Cat o2) {

if (o1.weight < o2.weight) {

return -1;

} else if (o1.weight > o2.weight) {

return 1;

} else {

return 0;

}

}

}

复制代码

这两个比较类实现了Comparator的compare()方法,并且分别实现了比较方式,现在改造一下Sorter排序类:

package com.cc.strategy;

public class Sorter {

public void sort(T[] arr, Comparator comparator) {

for (int i = 0; i < arr.length; i++) {

int minPos = i;

for (int j = i+1; j < arr.length; j++) {

minPos = comparator.comare(arr[j], arr[minPos]) == -1 ? j : minPos;

}

swap(arr, i, minPos);

}

}

private void swap(T[] arr, int i, int minPos) {

T temp = arr[i];

arr[i] = arr[minPos];

arr[minPos] = temp;

}

}

复制代码

现在,可以将原来Cat关于Comparable实现类的代码删掉,留下一个干净的对象了,因为排序实现我们放在了CatHeightComparator和CatWeightComparator中:

package com.cc.strategy;

public class Cat {

int weight, height;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值