首页 > 其他分享 >策略模式

策略模式

时间:2022-09-04 13:56:13浏览次数:46  
标签:arr return 策略 weight int 模式 foot public

策略模式

应用场景: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-20220904132019234

神奇吧?怎么做到的,就是在需要灵活变换的比较方法中,多加一个接口,把接口的实现留白给用户实现

类图

![image-20220904133157807](D:\Download\尚硅谷\msb\designer pattern\img\image-20220904133157807.png)

说白了就是 对策略进行开放拓展,排序的话,就可以有很多种策略

实际怎么运用?去代替if

标签:arr,return,策略,weight,int,模式,foot,public
From: https://www.cnblogs.com/mybloger/p/16654973.html

相关文章

  • 跨域、同源策略、CSRF 概念
    跨域当一个请求URL的协议、域名、端口三者之间任意一个与当前页面的不同即为跨域。同源策略同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能......
  • 火狐浏览器f12不显示firebug开发者模式问题总结
    大家在用火狐浏览器获取页面元素的时候是不是经常用firebug开发者模式?但是我们发现一个问题,F12按下后并没有显示firebug开发者模式,检查了一下firebug和firepath插件发现都......
  • 单例模式
    单例模式应用场景:在内存中只有一个实例,如xxxFactory,xxxMgr有八种单例,完美无缺的有两种,常用的却并非这两种1、packageorg.ali.singleton;/***Author:lury*Da......
  • 开启win10测试模式
    1.鼠标右键2.管理员shell3.命令4.重启电脑......
  • 如何将数据库设置为单用户模式 (SQL Server Management Studio 2008)
    即使设置此选项的用户已注销,数据库仍保持单用户模式。这时,其他用户(但只能是一个)可以连接到数据库。将数据库设置为单用户模式在对象资源管理器中,连接到SQLServer数......
  • 【设计模式】Java设计模式 -工厂模式
    【设计模式】Java设计模式-工厂模式......
  • 学习:python进阶 单例模式
        通过类的绑定方法来实现  如果用戶不通过绑定类的方法实例化对象,而是直接通过类名加括号方式实例化对象,那这样就不是单例模式了 ......
  • 5.1 Web开发模式
    目前主流的web开发模式有两种1.服务器端渲染的web开发模式  优缺点:  2.前后端分离的web开发模式  3.如何选择呢? ......
  • PostfreSQL-行安全策略
    除了通过GRANT提供的SQL标准权限系统之外,表还可以具有行安全策略,这些策略基于每个用户来限制正常查询可以返回哪些行,或者可以通过数据修改命令插入、更新或删除哪些行......
  • 模式匹配-让你 ts 类型体操水平暴增的套路
    Typescript支持泛型,也叫类型参数,可以对类型参数做一系列运算之后返回新的类型,这就是类型编程。因为类型编程实现一些逻辑还是有难度的,所以被戏称为类型体操。社区有用......