设计模式学习笔记--策略模式(Strategy Pattern)

策略模式(Strategy Pattern) ✅ 将每种行为或算法封装成独立的策略类,客户端通过选择不同的策略来改变行为。✅ 适用于需要在运行时动态改变算法或行为的场景。如果你有任何问题或需要进一步的解释,随时告诉我! 阅读详情

设计模式第一弹,发现在继续学习Java相关知识前,很有必要学习下设计模式,其中几个比较重要的设计模式其实在之前的使用中已经出现过很多次,但是由于没有学过设计模式,也就知其然不知其所以然的拿来用了,所以接下来准备好好整理学习设计模式,博客整理的内容均来自《Head First 设计模式》。下面开始整理第一个设计模式–策略模式

1.概念

策略模式:针对一组算法,将每一个算法分别封装起来,让它们之前可以互相替换,此模式让算法的变化独立于使用算法的客户。

2.设计原则

  • 找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。即:封装变化
    把会变化的部分取出并“封装”起来,以便以后可以轻易地改动或扩充此部分,而不影响到不需要变化的其他部分,总结起来就是:分开变化和不会变化的部分。

  • 针对接口编程,而不是针对实现编程
    将需要变化的行为放在分开的类中,此类专门提供某种行为接口的实现。

  • 多用组合,少用继承
    区分“有一个”(组合)关系和“是一个”(继承)关系,使用 组合建立系统具有很大的弹性,不仅可以将算法族封装成类,更可以“在运行时动态的改变行为”。

3.使用举例

借用《Head First 设计模式》书上的实例:

3.1 假设鸭子类(Duck),有许多不同的子类:
绿头鸭(MallardDuck)
红头鸭(RedHeadDuck)
橡皮鸭(RubberDuck)
诱饵鸭(DecoyDuck)
模型鸭(ModelDuck)
子类继承父类的行为:呱呱叫(quack())和游泳(swim())
嗯,一切看起来都很正常,通过继承,子类得到父类的行为,这样子类也会呱呱叫和游泳;

3.2 现在想让某些鸭子具有新的行为:飞行(fly())

  • 首先想到的是在需要具有飞行行为的子类中添加新的方法(fly())不就解决了吗!嗯,这是在子类比较少的情况下可以使用的“笨办法”,一旦子类很多,而且也许好几个子类具有的飞行行为是一样的呢?这样不就产生了大量重复代码吗?这是我们需要避免的!

  • 其次想到的是在父类(Duck)中添加行为(fly()),其子类通过继承就拥有飞行行为了。看似问题解决了,但是想想这样子所有的子类就都拥有了飞行的行为,包括橡皮鸭(不应该具有飞行的行为),所以这种方法行不通,因为通过继承,一旦改变父类中的某些行为,所有子类都将受影响,导致某些不应该变化的子类也发生了变化,这种改变将是牵一发而动全身的;
    通过继承来提供Duck的行为的缺点:

    • 导致代码在多个子类中重复
    • 运行时的行为不容易改变
    • 很难知道所有鸭子的全部行为
  • 接下来想到的方法是通过接口实现,通过将变化的行为(呱呱叫,游泳,飞行)封装到单独的接口中,某个子类想要拥有哪种行为,实现那种接口,重写其方法就行了,看似能解决暂时的问题,然而一旦行为增加(比如每隔一周增加一种新的行为)或者子类增加,这样将造成严重的混乱局面,所以,这种方法也不合适。
    通过把会变的行为提取出来设计成一个接口的缺点:

    • 导致重复代码变多
    • 导致代码无法进行复用

3.3 接下来就是策略模式展现魅力的时候了
通过以上思路,了解到添加新的行为并不是那么容易,这个过程是变化的,根据设计原则:封装变化,我们知道变化的部分是鸭子类的行为,而不变的是鸭子类的继承关系,把握住了变化与不变的内容,于是进行如下设计:建立对应行为的接口,比如创建飞行行为的接口(FlyBehavior),其中有个方法fly(),然后所有的飞行行为类都实现它,实现其中的fly()方法,结构如下:
这里写图片描述

其他行为以此类推,这里就不重复了。

接下来整合鸭子的行为,做法是这样的:

  • 首先,在Duck类中定义对应行为接口的实例,例如上面的飞行行为:
    protected FlyBehavior flyBehavior;
  • 然后,实现调用接口行为的方法,依然使用飞行行为举例:
    public void performFly() {
        flyBehavior.fly();
    }
  • 接下来是在子类中指定其应具有的行为
public class MallardDuck extends Duck {

    public MallardDuck() {
        flyBehavior =new FlyNoWay();//这里指定的飞行行为是“不会飞”
    }
}

嗯,以上,基本结构出来了,接下来进行测试,创建测试类:

    public static void main(String[] args) {
        Duck mallard = new MallardDuck();
        mallard.performFly();//调用了MallardDuck类的飞行方法,看上面,MallardDuck类指定的飞行行为是“不会飞”
    }

以上,简单总结了策略模式的使用,使用策略模式的优点如下:

  • 采用良好的oo软件设计原则
  • 分开变化和不会变化的部分
  • 针对接口编程

4. 实例代码

实例代码根据《Head First 设计模式》书上的代码进行编写测试,如下:

4.1 首先,封装变化,即封装行为类:

package DuckInterface;

public interface FlyBehavior {
    public void fly();
}
package DuckFlyBehavior;

import DuckInterface.FlyBehavior;

public class FlyWithWings implements FlyBehavior {
    public void fly() {
        System.out.println("-->I can fly!!!");
    }
}
package DuckFlyBehavior;

import DuckInterface.FlyBehavior;

public class FlyNoWay implements FlyBehavior {
    public void fly() {
        System.out.println("-->I cannot fly...");
    }
}

注:另外一个行为:呱呱叫(quack)结构与飞行行为结构类似,这里就不贴出代码了;

4.2 接下来是定义鸭子父类:

package DuckAbstract;

import DuckInterface.FlyBehavior;
import DuckInterface.QuackBehavior;

public abstract class Duck {

    protected FlyBehavior flyBehavior;
    protected QuackBehavior quackBehavior;

    public Duck() {
    }

    public void performFly() {
        flyBehavior.fly();
    }

    public void performQuack() {
        quackBehavior.quack();
    }

    // 所有鸭子都具有游泳的行为,所以游泳放在父类中,所有子类都能继承这个方法
    public void swim() {
        System.out.println("-->all ducks can swim");
    }

    public abstract void display();
}

可以看到,在鸭子父类中定义了封装好的行为,并调用接口的方法,具体调用哪个方法并不知道,需要根据具体的子类进行调用,下一步就是具体定义不同子类拥有的具体行为;

4.3 创建子类,继承父类,定义好不同子类拥有的具体行为,这里以绿头鸭(MallardDuck)示范:

package DuckInstence;

import DuckAbstract.Duck;
import DuckFlyBehavior.FlyNoWay;
import DuckQuackBehavior.MuteQuack;

public class MallardDuck extends Duck {

    public MallardDuck() {
        quackBehavior = new MuteQuack();// 绿头鸭具有MuteQuack的行为,就是“不会叫”
        flyBehavior = new FlyNoWay();// 绿头鸭具有FlyNoQWay的行为,就是“不会飞”
    }

    @Override
    public void display() {
        System.out.println("-->this is MallardDuck");
    }

}

4.4 最后一步,进行测试:

package DuckInstence;

import DuckAbstract.Duck;

public class TestDuck {

    public static void main(String[] args) {
        Duck mallard = new MallardDuck();
        mallard.performFly();
        mallard.performQuack();
    }
}

在主方法中创建MallardDuck类的对象,调用其行为,结果显示如下:
这里写图片描述

以上,通过使用策略模式,很好的解决了不同子类具有不同行为,但是又互不影响的问题,达到了良好的OO设计必须具备可复用、可扩充、可维护 的特性

LeRobot — 基于 PyTorch 的真实世界机器人学习框架(一)- 核心框架模块解析 LeRobot 是一个开源的机器人学习框架,由 Hugging Face 开发,旨在降低机器人学的准入门槛。该框架提供完整的机器学习流程支持,包括数据采集、训练、评估和部署。核心模块涵盖数据集标准化、策略算法、硬件抽象和强化学习组件,采用模块化设计实现灵活扩展。通过集成 Hugging Face Hub,用户可以轻松共享数据集和预训练模型。LeRobot 特别注重真实世界的机器人应用,支持多种前沿算法如模仿学习、视觉语言动作模型等,并提供统一的硬件接口和仿真环境适配。 阅读详情

相关推荐

光电容积脉搏波PPG信号分析笔记

脉搏波信号PPG分析笔记

teresa_zp的专栏 6478

设计模式学习笔记---策略模式strategy pattern(Java版)

一、场景 市场人员接到单之后的报价策略,比如普通用户或老客户,还是小批量或大批量。 二、实质 策略模式对应于解决某一个问题的一个算法族,允许用户从该算法族中任选一个算法解决某一问题,同时可以方便的更换算法或者增加新的算法。并且由客户端决定调用那个算法。(分离算法,选择实现。) 三、示例1、未使用策略模式package com.lgd.strategy;/** * 实现容易,

吃果冻不吐果冻皮 1294

VSCode 降低适用版本并且关闭自动更新

官方表示,提高了远程服务器构建工具链的最低要求,更新了对 glibc 的要求,需要最低2.28版本。最快的方法是把vs code的版本降到1.85(为什么是这个版本呢?打开VS Code的官方网站(https://code.visualstudio.com/)通过查看可以知道,具体的版本没有直接显示分类,他是根据发布日期来分类的同时和版本匹配。在网站的顶部导航栏中找到”Updates”按钮,点击进入下载页面。找了半天一直没发现,原来就在紧挨着的下面。远程主机不满足运行vs code服务器的先决条件。

Sunflower的博客 9583

C#设计模式-【HeadFirst设计模式学习笔记】重学策略模式(Strategy Pattern)

从意义上看,策略模式提供了这样一种便利: 当一系列对象包含多种行为,并且这些行为会有不同的算法实现的时候,策略模式就是一个易于配置的应对方法。 在HeadFirst设计模式中,第一章先让我们无意中实现了这一模式:) 不得不感叹作者的苦心。我们设想如下的一个用例: 公司在开发一个鸭子游戏,游戏当中有几种不同的鸭子,鸭子将可以执行鸣叫,飞行等行为。我们如何使用面向对象的方法来实现它? ...

weixin_30642029的博客 117

疫情数据分析的“核武器”!JHU CSSE COVID-19数据集超深度解析与实战指南(附代码)

在面对这场没有硝烟的战争时,除了医护人员在前线与病毒搏斗,还有一群默默的英雄——数据科学家和分析师,他们利用手中的“数据武器”,昼夜不停地监测、分析、预测疫情走势,为政府决策、资源调配、公众科普提供了至关重要的支撑。同时,由于某些国家(如美国、加拿大、澳大利亚、中国等)的数据细化到省/州级别,为了得到国家层面的总数据,我们需要按国家和日期进行聚合。正是在这样的背景下,经过这些步骤,我们已经得到了一个包含了累计数据、每日新增数据和活跃病例数的完整数据集,可以开始进行深入的分析和可视化了!

wylee的博客 1165

双目相机立体匹配算法概述(含Python代码)

立体匹配任务是计算机视觉中的一个重要问题,旨在从一对具有相同场景的图像中估计每个像素的视差(disparity)。本文对现有的传统算法和深度学习算法进行了综述,以便于各位选择合适的立体匹配算法用于深度估计或三维建模。

m0_59257547的博客 8293

OpenCV 2 学习笔记(10): 算法的基本设计模式<1>:策略模式(strategy pattern)

C++最大的优势是什么,就是面向对象,我们可以把属性和方法都封装到一个类里面。这样我们很容易变换一种方法或者可以更容易的创建复杂的程序。而且这样可以将复杂的程序封装起来,只留一个简单易用的接口。         下面我们想创建一个简单的算法,它会确定图像中有给定颜色的所有像素。算法中图像和颜色作为输入,输出为表示有给定颜色的一个二值图像。还有一个给定的幅度范围。 // get the iter

Fred、的窃窃私语 2189

YOLO26原创优化:SPPF优化 | 新一代高效可形变卷积DCNv4如何做二次创新?高效结合SPPF

如何跟YOLO26结合:1) SPPF高效结合

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 357

学习笔记【23种设计模式-第二十二节:Strategy Pattern 策略模式】

Strategy Pattern 策略模式 简述: 策略模式中,定义算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。 这算法体现了几个设计原则:① 把变化的代码从不变的代码中分离出来;② 针对接口编程而不是具体类(定义了策略接口);③多用组合/聚合,少用继承(客户通过组合方式使用策略)。 角色 Context类有成员变量strategy或其他的策略接口,至于需要使用到哪个策略,我们可以在构造器中指定。 例子 鸭子:有玩具鸭、北京鸭和野生鸭,所有鸭子都能有用,但并

qq_53273362的博客 153

【Claude Code】Unable to connect to API 报错原因与排查解决全流程

深入分析 Claude Code 中 Unable to connect to API 系列报错的根因,涵盖 ECONNREFUSED、ECONNRESET、ETIMEDOUT 等 6 种变体,提供从网络连通性检测、代理配置到 LLM 网关路由的完整排查路径,帮助开发者快速恢复 Claude Code 的正常使用。

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 2853

使用 Python 构建 Reddit 热帖爬虫:抓取热门讨论帖和评论

在现代互联网中,Reddit 被誉为全球最大、最活跃的讨论平台之一,汇聚了各种主题的帖子、评论和社交互动。因此,抓取 Reddit 上的热门帖子和评论可以为我们提供一个丰富的文本数据源,可以用于情感分析、话题建模、趋势分析等应用。Reddit 提供了官方的 API,可以让开发者获取包括帖子、评论、用户信息等在内的各种数据。我们可以结合上述方法,抓取多个热门帖子,并将每个帖子的标题、作者、发布时间和评论内容保存到一个数据结构中。每个帖子的对象包含了丰富的信息,如标题、内容、发布时间、作者等。

2201_76125261的博客 382

Head.First设计模式学习笔记之策略设计模式(Strategy Pattern)

1、该用例表明,在设计中,要多用组合(composition),少用继承(extend). 2、使用多态,实现同一行为的不同表现。 3、封装变化。 4、在声明实例时,多用接口,尽量不用具体类(针对接口编程,不针对实现编程)。 5、多使用组合以提高程序的可维护性和可扩展性,提高复用程度。 Strategy Pattern描述:定义了算法簇,分别封装起来,让他们之间可以分别替换。此模式让...

liwanchun_xd 116

CVAEGAN实现锂离子电池EIS数据增强:基于健康状态的阻抗谱生成

本文提出了一种基于CVAEGAN的锂离子电池EIS数据增强方法。该方法结合了变分自编码器和生成对抗网络的优点,能够根据指定的健康状态(SoH)生成高质量的EIS阻抗谱数据。文章详细介绍了数据预处理流程、模型架构设计(包括编码器、解码器和判别器),并提供了完整的PyTorch实现代码。通过条件生成的方式,该方法可以有效解决电池健康评估中标注数据不足的问题,为基于数据驱动的电池诊断提供更丰富的训练样本。实验结果表明,生成的EIS数据具有良好的真实性和多样性,可用于增强电池健康状态评估模型的性能。

huanghm88的专栏 499

23种设计模式之策略模式(Strategy Pattern)

本篇文章将23种设计模式中的策略模式,此篇文章为一天学习一个设计模式系列文章,后面会分享其他模式知识。

小威的博客 1万+

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

设计模式-策略模式-Strategy Pattern

策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列的算法,并将每一个算法封装起来,使它们可以互换使用,算法的变化不会影响使用算法的用户。策略模式的优点包括算法的封装和切换的灵活性,以及算法可独立于使用它的客户端变化。:如果算法的实现非常复杂,或者算法可能会随着时间而变化,策略模式可以帮助管理这种复杂性,使得算法的变化不会影响到使用算法的代码。:在需要根据不同条件动态切换算法的场景中,策略模式可以提供灵活的算法切换机制,例如,根据输入数据的特性选择不同的算法。

wesigj的博客 1456

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

C++设计模式——策略模式(Strategy Pattern)

C++设计模式——策略模式(Strategy Pattern) 微信公众号:幼儿园的学霸 目录 文章目录C++设计模式——策略模式(Strategy Pattern)目录定义实现示例传统的策略模式实现使用函数指针实现策略模式工厂模式和策略模式对比总结参考资料 定义 Define a family of algorithms,encapsulate each one,and make them interchangeable. 定义一组算法,将每个算法都封装起来,并且使它们之间可以互换 策略模式是指定

leonardohaig的博客 4774

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

策略模式 Strategy Pattern

策略模式「strategy pattern 」(也称为policy pattern)是一种行为软件设计模式「behavioral」,可以在运行时选择算法。代码不是直接实现单个算法,而是接收运行时指令,指示使用一系列算法「a family of algorithms」中的哪一个。在上面的UML类图中,Context类不直接实现算法。相反,Context引用 用于执行算法的Strategy接口(Strategy.algorithm()),这使得Context独立于算法的实现方式。

DachuiLi的博客 1359

设计模式-19策略模式Strategy Pattern

策略模式是一种行为设计模式,通过定义一系列可互换的算法并将其封装,使算法能独立于使用它的客户端而变化。该模式适用于需要动态切换不同算法或行为的场景,可避免大量条件判断语句。其核心结构包括策略接口、具体策略类和使用策略的上下文类。实现时,先定义策略接口,然后创建具体策略类实现接口方法,最后通过上下文类动态设置和切换策略。示例展示了支付系统中的多种支付策略(信用卡、PayPal、银行转账)的灵活切换,体现了策略模式的可扩展性和解耦优势。 (149字)

d3y1`5 81_09 1088

C#设计模式之策略模式(Strategy Pattern)

概述:        策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理。策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是:“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。下面就以一个示意性的实现讲解策略模式实例的结构。 这个模式涉及到三个角色: 环境(Context)角色:持有一个St

donnie88888888的专栏 4065

【设计模式】策略模式(Strategy Pattern)详解

策略模式(Strategy Pattern)是一种行为型设计模式,

qq_59344127的博客 1839

策略模式 (Strategy Pattern)

策略模式是一种行为设计模式,它将算法封装为独立对象,使它们可互换。该模式包含策略接口(定义算法)、具体策略类(实现算法)和上下文类(使用策略)。适用于需要动态切换算法或隐藏算法细节的场景。示例展示了支付方式(信用卡/支付宝/微信)和排序算法(冒泡/选择排序)的实现,通过策略模式可以灵活切换不同算法而不影响客户端代码,提高系统的扩展性和可维护性。

懵萌长颈鹿的博客 1368

23种设计模式——策略模式 (Strategy Pattern)​详解

本文介绍了23种经典设计模式之——策略模式 (Strategy Pattern)​的说明及使用

Meteors.的博客 837

设计模式-策略模式(Strategy Pattern)

策略模式 定义 定义了一组算法,将每个算法都封装起来,并且使它们之间可以互换,且算法的变化不会影响使用算法的客户。它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。 类型 行为型。 角色 抽象策略(Strategy):定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。 具体策略...

kaven 1653

设计模式十:策略模式(Strategy Pattern)

0、相关文章:=======(阅读量6376)1、详解====1.1、概念定义一系列的算法,把它们一个个封装起来,并且使它们可以互相替换。本模式使得算法可独立于使用它的客户而变化。1.2、使用场景一个类定义了多种行为,并且这些行为在这个类的方法中以多个条件语句的形式出现,那么可以使用策略模式避免在类中使用大量的条件语句。1.3、UML结构图分析可以看到,策略模式中主要有以下几个角色:Strategy 接口,用于定义算法的固定套路。

2501_90425746的博客 1821

23种设计模式-19策略模式(Strategy Pattern)

策略模式是在开发中最常见的设计模式之一,本文介绍了策略的基本原理及使用场景,以及基于 java 代码的普通实现和基于Spring 的实现案例。

不开心就吃辣 1872
上一篇: Android入门---下拉刷新上拉加载更多策略的实现
下一篇: AndroidStudio中百度地图接口使用配置相关总结
classTC
博客等级 码龄15年 46粉丝 55原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值