当前位置:

首页 > 编程开发 > Java的策略模式用代码怎么实现

Java的策略模式用代码怎么实现

策略模式策略模式属于Java23种设计模式中行为模式之一,那先看看什么是策略模式。1、什么是策略模式策略模式的定义:该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。其实我们在现实生活中常常遇到实现某种目标存在多种策略可供选择的情况,例如,出行旅游可以乘坐飞机、乘坐火车、骑自行车或自己开私家车等。或者比如网购,你可以选择工商银行、农

本文目录

      策略模式

      策略模式属于Java 23种设计模式中行为模式之一,那先看看什么是策略模式。

      1、什么是策略模式

      策略模式的定义:

      该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。

      其实我们在现实生活中常常遇到实现某种目标存在多种策略可供选择的情况,例如,出行旅游可以乘坐飞机、乘坐火车、骑自行车或自己开私家车等。或者比如网购,你可以选择工商银行、农业银行、建设银行等等,但是它们提供的算法都是一致的,就是帮你付款。

      在软件开发中也会遇到相似的情况,当实现某一个功能存在多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能。

      2、策略模式的优缺点

      优点:

      • 多重条件语句不易维护,而使用策略模式可以避免使用多重条件语句

      • 提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码

      • 提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的

      • 提供了对开闭原则的完美支持,可以在不修改原代码的情况下,灵活增加新算法把算法

      • 的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者的分离

      缺点:

      • 客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类

      • 策略模式造成很多的策略类,增加维护难度

      3、策略模式的结构

      1.抽象策略类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。

      2.具体策略类:实现了抽象策略定义的接口,提供具体的算法实现。

      3.环境类:持有一个策略类的引用,最终给客户端调用。

      结构图:

      Java的策略模式用代码怎么实现

      4、代码实现

      现在有三只鸭子: 绿毛鸭、红毛鸭、小鸭子(小鸭子还不会飞)

      现在定义一个鸭子的父类:里面有都会叫的方法,有显示外观的方法(因为每只都不一样,就需要子类重写)

      还会飞行 (这里使用策略模式)

      public  abstract class duck {
          //鸭子都会叫:
          public void quack(){
              System.out.println("嘎嘎嘎");
          }
          //鸭子的外观,因为都不一样,所以由子类去实现
          public abstract void display();
      	
      	//以下使用策略模式:
          //在父类中持有该接口,并由该接口代替飞行行为(组合)
          private Flying flying;
          //提供set方法
          public void setFlying(Flying flying) {
              this.flying = flying;
          }
          public void fly(){
              flying.Fly();
          }
      }

      定义一个飞行接口:

      /**
       * 策略接口:实现了鸭子的飞行行为
       */
      public interface Flying {
          void Fly();
      }

      我们知道策略模式就是把需要用的算法封装起来,就在另一个包内封装了会飞和不会飞的两个方法:

      会飞(继承至上面的飞行接口,重写飞行方法):

      public class FlyWithWin implements Flying {
          @Override
          public void Fly() {
              System.out.println("我会飞");
          }
      }

      不会飞:

      public class FlyNoWay implements Flying {
          @Override
          public void Fly() {
              System.out.println("我不会飞行");
          }
      }

      注意: 上面这两个方法我是把他们单独封装起来,当做算法族,然后程序需要使用里面某个算法的时候,程序不会受算法改变的影响,因为这里面的算法最终效果是一致的

      红毛鸭类:

      /**
       * 红色鸭子
       */
      public class RedDuck extends duck{
          public RedDuck(){
              super();
              //给鸭子注入飞行的能力,这里就是通过算法族里面的会飞的算法
              super.setFlying(new FlyWithWin());
          }
          @Override
          public void display() {
              System.out.println("我是红色的鸭子");
          }
      }

      绿毛鸭:

      /**
       *
       * 绿色鸭子
       */
      public class GreenDuck extends duck{
          public GreenDuck(){
              super();
              //给鸭子注入飞行的能力,这里也是通过算法族里面的会飞的算法
              super.setFlying(new FlyWithWin());
          }
          @Override
          public void display() {
              System.out.println("我是绿色的鸭子");
          }
      }

      小鸭子类(不会飞):

      /**
       * 小鸭子,还不会飞
       */
      public class SamllDuck extends duck{
          public SamllDuck(){
              super();
              //小鸭子不会飞,所以使用了算法族里面不会飞的算法
              super.setFlying(new FlyNoWay());
          }
      
          @Override
          public void display() {
              System.out.println("我还是小鸭子");
          }
          //因为小鸭子和大鸭子的叫声不一样,所以重写叫声方法
          public void quack(){
              System.out.println("嘎~嘎~嘎");
          }
      }

      测试类:

      public class Test {
          public static void main(String[] args) {
              System.out.println("***测试鸭子程序***");
              duck d = null;
      		//这下面是轮流运行!!!!  
              d = new RedDuck();  //测试红色的鸭子
              d = new GreenDuck();  //测试绿色的鸭子
              d = new SamllDuck();  //测试小鸭子
              d.display();
              d.quack();
              d.fly();
              System.out.println("***测试完毕***");
          }
      }

      当使用红毛鸭为对象时:

      ***测试鸭子程序***
      我是红色的鸭子
      嘎嘎嘎
      我会飞
      ***测试完毕***

      当使用绿毛鸭为对象时:

      ***测试鸭子程序***
      我是绿色的鸭子
      嘎嘎嘎
      我会飞
      ***测试完毕***

      当使用小鸭子为对象时:

      ***测试鸭子程序***
      我还是小鸭子
      嘎~嘎~嘎
      我不会飞行
      ***测试完毕***

      5、策略模式的应用场景

      1.一个系统需要动态地在几种算法中选择一种时,可将每个算法封装到策略类中

      2.一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,可将每个条件分支移入它们各自的策略类中以代替这些条件语句

      3.系统中各算法彼此完全独立,且要求对客户隐藏具体算法的实现细节时

      4.系统要求使用算法的客户不应该知道其操作的数据时,可使用策略模式来隐藏与算法相关的数据结构

      5.多个类只区别在表现行为不同,可以使用策略模式,在运行时动态选择具体要执行的行为

      本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
      作者最新文章
      编程开发 Java
      相关文章 更多
      Java单元测试入门:使用JUnit 5编写第一个测试用例
      Java单元测试入门:使用JUnit 5编写第一个测试用例

      面向初学者的JUnit 5实用入门指南。从测试概念、Maven依赖配置,到手把手编写首个单元测试用例及断言验证,助你掌握Java单元测试的核心流程。

      Java变量未初始化报错解析:局部变量与成员变量默认值差异
      Java变量未初始化报错解析:局部变量与成员变量默认值差异

      深入解析Java中局部变量未初始化编译报错与成员变量自动赋予默认值的机制差异,涵盖JVM内存分配、编译期确定性赋值检查与实际排查修复方案。

      Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat
      Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat

      详细讲解在Java中获取当前系统时间并进行格式化输出的两种核心方案:基于Java 8全新日期时间API的DateTimeFormatter与传统遗留的SimpleDateFormat,包含完整代码示例、线程安全机制对比及生产选型建议。

      Java中final与static final常量的定义及初始化规则
      Java中final与static final常量的定义及初始化规则

      深入解析Java中final变量与static final常量的定义、内存语义、初始化时机及合法赋值路径,涵盖编译期常量优化与实战避坑指南。

      Java抽象方法与接口方法的区别及选型建议
      Java抽象方法与接口方法的区别及选型建议

      深入对比Java中抽象类抽象方法与接口方法的语法演进、设计意图及运行期差异,并提供清晰的架构选型决策流程与实战范例。

      Java实现HTTP请求与JSON解析的完整代码示例
      Java实现HTTP请求与JSON解析的完整代码示例

      本文提供Java标准库HttpClient发起HTTP GET/POST请求并结合Jackson进行JSON数据反序列化与序列化的完整代码示例与工程实践指南。

      Java递归出现StackOverflowError的原因分析及栈空间优化方案
      Java递归出现StackOverflowError的原因分析及栈空间优化方案

      详细分析Java递归调用出现StackOverflowError的原因,结合代码说明线程栈、栈帧和递归深度之间的关系,并介绍终止条件排查、迭代改写、减少栈帧开销以及通过-Xss调整JVM栈空间的方法。

      Java空指针异常(NPE)的代码排查与修复实例
      Java空指针异常(NPE)的代码排查与修复实例

      针对Java中常见的NullPointerException(NPE),本文从堆栈日志定位、典型代码触发场景、具体修复代码对比到防御体系进行系统讲解,提供实用且易上手的排查与修复方案。

      selenium上传文件教程本地文件路径设置方法
      selenium上传文件教程本地文件路径设置方法

      深入解析Selenium处理文件上传的技术细节,涵盖标准HTML控件的路径直接注入法与非标准控件的系统级模拟方案,提供Windows与Linux环境下的路径设置最佳实践及常见异常排查。

      大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景
      大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景

      针对大数据工程场景,系统对比Java、Scala与Python在执行性能、生态结合、开发效率和维护成本上的核心差异,给出清晰的架构选型依据与落地方案。

      查看更多
      精品专题 更多
      装机必备
      装机必备

      正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

      Windows
      Windows

      正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

      PDF教程
      PDF教程

      正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

      Mac软件 更多
      讯飞智作 网页版
      讯飞智作 网页版
      Windows/ macOS/ Linux

      讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

      火山引擎 网页版
      火山引擎 网页版
      Windows/ macOS/ Linux

      火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

      Aperty macOS版
      Aperty macOS版
      macOS

      Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

      WINDOWS 更多
      讯飞智作 网页版
      讯飞智作 网页版
      Windows/ macOS/ Linux

      讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

      火山引擎 网页版
      火山引擎 网页版
      Windows/ macOS/ Linux

      火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

      PixTV 网页版
      PixTV 网页版
      Windows

      PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。