策略模式--Strategy

个人理解

我先把自己的结论放前面了,学习完策略模式,给我的感觉:

  1. 又加深了对java多态的理解,本质上策略模式就是java面对对象多态的实现
  2. 策略某种意义上,可以理解时选择语句if…else或者switch…case的变种,更加全面,适用性更强

本文举的例子参考jdk java.lang.Comparable接口

demo的目的:针对任意类型的arraylist的进行排序
本案例采用冒泡排序

//创建一个cat类
/**
 * @Description: TODO
 * @author: qinlei
 * @date: 2020年06月10日 9:03
 */
public class Cat {
    private int weight;
    private int height;
    private int age;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    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 Cat() {
    }

    public Cat(int weight, int height, int age) {
        this.weight = weight;
        this.height = height;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Cat{" +
                "weight=" + weight +
                ", height=" + height +
                ", age=" + age +
                '}';
    }
}

创建一个比较器的函数式接口

@FunctionalInterface
public interface Comparable<T> {
    int compareTo(T t1,T t2);
}

创建一个Cat类的高度比较器实现比较器接口

/**
 * @Description: 数值小的放前面
 * @author: qinlei
 * @date: 2020年06月10日 9:03
 */
public class CatHeightComparable implements Comparable<Cat>{

    @Override
    public int compareTo(Cat t1, Cat t2) {
        if(t1.getHeight()<t2.getHeight()) return -1;
        else if (t1.getHeight()>t2.getHeight()) return 1;
        else return 0;
    }
}

创建一个Cat类的宽度比较器实现比较器接口

/**
 * @Description: 数值大的放前面
 * @author: qinlei
 * @date: 2020年06月10日 9:03
 */
public class CatWeightComparable implements Comparable<Cat>{

    @Override
    public int compareTo(Cat t1, Cat t2) {
        if(t1.getWeight()<t2.getWeight()) return 1;
        else if (t1.getWeight()>t2.getWeight()) return -1;
        else return 0;
    }
}

比较的方法

	public void sort (ArrayList<T> list ,Comparable<T> comparable){
        for (int i = 0; i < list.size(); i++) {
            int min = i;
            for (int j = i + 1;j<list.size();j++){
                min = comparable.compareTo(list.get(j),list.get(min))==-1?j:min;
            }
            swap(list,i,min);
        }
    }

    public void swap(ArrayList<T> t,int i, int j){
        T temp = t.get(i);
        t.set(i,t.get(j));
        t.set(j,temp);
    }

测试

public static void main(String[] args) {
        ArrayList<Cat> cats = new ArrayList<>();
        cats.add(new Cat(2,2,2));
        cats.add(new Cat(1,1,1));
        cats.add(new Cat(4,4,4));
        System.out.println("排序前:"+cats);
        SortDemo<Cat> sortDemo = new SortDemo<>();
        //比较宽度
        sortDemo.sort(cats,new CatWeightComparable());
        System.out.println("按宽度排序后:"+cats);
        //比较宽度
        sortDemo.sort(cats,new CatHeightComparable());
        System.out.println("按高度度排序后:"+cats);
    }

在这里插入图片描述

细心的朋友可能发现了,所写的比较器接口有个注解@FunctionalInterface

  • 该注解是jdk8以后的注解,表示该接口是个函数式接口.主要用于编译级错误检查,加上该注解,当你写的接口不符合函数式接口定义的时候,编译器会报错。
  • 该接口中只能有一个抽象方法
  • 这样的话就更方便了,因为可以使用lambda表达式

例如

上述例子创建了高度比较器,宽度比较器

再将比较器实例化后传入sort()方法

使用lambda表达式的比较,不需要单独创建一个类实现Comparable比较器接口了

如:

public static void main(String[] args) {
        ArrayList<Cat> cats = new ArrayList<>();
        cats.add(new Cat(2, 2, 2));
        cats.add(new Cat(1, 1, 1));
        cats.add(new Cat(4, 4, 4));
        System.out.println("排序前:" + cats);
        SortDemo<Cat> sortDemo = new SortDemo<>();
        //比较宽度
//        sortDemo.sort(cats,new CatWeightComparable());
//        System.out.println("按宽度排序后:"+cats);
        //比较宽度
//        sortDemo.sort(cats,new CatHeightComparable());
//        System.out.println("按高度度排序后:"+cats);
        //比较年龄
        sortDemo.sort(cats, (t1, t2) -> {
            if (t1.getAge() < t2.getAge()) {
                return -1;
            } else if (t1.getAge() > t2.getAge()) {
                return 1;
            } else {
                return 0;
            }
        });
        System.out.println("按年龄排序后:" + cats);
    }

结果:
在这里插入图片描述

DEMO案例的总结

上述中的高度比较器(CatHeightComparable) 宽度比较器(CatWeightComparable) 还有使用lambda表达式实现的年龄比较
就是一个个的比较策略.整体就是一个策略模式.

应用场景

做地图服务时,不同的标记点有不同的图标样式,大小等等等

某个游戏,不同身份的用户(VIP,超VIP)他们的服饰等等豪华程度不同

简单来说,就是本来可以使用选择语句来实现的代码块,但是实现起来代码量重复量大且没有很高的可扩展性,不容易维护,这时就可以使用策略模式.
从这里就可以看出策略模式有这么两个优点:

  • 可以把公共的代码移到父类里面,从而避免代码重复。

  • 使用策略模式可以避免使用多重条件(if-else)语句。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qlanto

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值