当前位置: 首页 > news >正文

策略模式(Strategy)

一、策略模式:

封装不同的算法,实现客户端调用时可以根据需求,在不修改原算法的情况下,可以很好的切换不同的算法,实现不同的需求;即不同的策略实现不同的功能;比如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);}
}


http://www.mrgr.cn/news/90052.html

相关文章:

  • iOS主要知识点梳理回顾-3-运行时
  • 上传文件防木马函数
  • 使用Termux和Ollama在Android设备上构建与运行AI模型
  • 【紫光同创PG2L100H开发板】盘古676系列,盘古100Pro+开发板,MES2L676-100HP
  • 【嵌入式 Linux 音视频+ AI 实战项目】瑞芯微 Rockchip 系列 RK3588-基于深度学习的人脸门禁+ IPC 智能安防监控系统
  • 【DeepSeek论文精读】2. DeepSeek LLM:以长期主义扩展开源语言模型
  • react 路由配置:从入门到精通
  • 解锁 DeepSeek 模型高效部署密码:蓝耘平台深度剖析与实战应用
  • 区块链技术未来发展趋势(人工智能和物联网领域)
  • 【计算机网络】TCP/IP 网络模型有哪几层?
  • 寒假集训思维训练1题解
  • [Meet DeepSeek] 如何顺畅使用DeepSeek?告别【服务器繁忙,请稍后再试。】
  • deepseek v3网络结构源码分析笔记
  • 5. 【.NET 8 实战--孢子记账--从单体到微服务--转向微服务】--微服务基础工具与技术--Nacos
  • Win10 部署llama Factory 推荐教程和遇到的问题
  • 大数据项目4:基于spark的智慧交通项目设计与实现
  • 【通俗易懂说模型】反向传播(附多元分类与Softmax函数)
  • 【虚幻引擎UE】UE4.23到UE5.5的核心功能变化
  • LLMs之DeepSeek r1:TinyZero(复现 DeepSeek R1 Zero 的核心功能)的简介、安装和使用方法、案例应用之详细攻略
  • [概率论] 随机变量
  • CPLD实现SPI通信
  • android系统的overlay机制
  • Odoo17学习笔记
  • 题解 洛谷 Luogu P1983 [NOIP 2013 普及组] 车站分级 拓扑排序 C++
  • 【1.05版】wordpressAI插件批量生成文章、图片、长尾关键词、文章采集、AI对话等
  • fps动作系统5:角色冲刺