设计模式入门:策略模式

news2024/11/25 12:21:49

现有一套模拟鸭子游戏,可以一边游泳,一边呱呱叫。

每种鸭子都会呱呱叫和游泳,只是外观不同。因此,quack和swim放在父类中,display放在子类中实现。

增加新的功能:鸭子飞翔。

1 我们可能想到直接在父类中增加fly的方法。

 但如果出现一个橡皮鸭,我们只能在子类中覆盖fly方法,FlyNoWay,同时,也需要覆盖quack方法,吱吱叫。如果还有其它的鸭子子类,如诱饵鸭等等,那么就需要在各自的子类中进行修改,检查是否需要修改quack和fly方法。这(继承)导致的问题会有:

  • 代码在多个子类中重复
  • 运行时的行为不容易改变
  • 很难指导所有鸭子的全部行为
  • 改变会牵一发动全身,造成其它鸭子不想要的改变

2 如果将fly和quack从超类中独立出来,设计为两个新的接口呢?

 这个改变好像会导致重复的代码更多,更加愚蠢?

---------------------------------------------------------------------------------------------------------------------------------

这本书是用的Java,如果这里是C++,是不是会想到flyable和quackable是接口,然后再有类继承接口,最后Duck子类实现多类继承?多类继承我还没有具体深入研究过,只是感觉可能会提高复杂度。

 或者直接是继承多个超类,需要覆盖的在子类中覆盖?

---------------------------------------------------------------------------------------------------------------------------------

 这里引出了一个设计原则:找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。(会变化的部分封装起来,以后就可以轻易改动或扩充此部分,而不影响其它不需要变化的部分)

第二个设计原则:针对接口编程,而不是针对实现编程

鸭子的行为将被放在分开的类中,此类专门提供某行为接口的实现。这样,鸭子类就不再需要知道行为的具体实现细节。

鸭子类不负责实现Flyable和Quackable接口,而是新建一组类去专门实现这两个接口,这些类就叫做行为类。以往,行为来自Duck超类的具体实现,或者继承某个接口并由子类自行实现而来。

这样设计,可以让飞行和呱呱叫的动作被其它对象复用,因为这些动作已经与鸭子类无关了。而且我们可以新增一些行为,不会影响到既有行为类,也不会影响到使用到飞行行为的鸭子类。 

复用的具体操作为(组合),在Duck类中加入两个实例变量,分别为flyBehavior, quackBehavior,每个鸭子对象都会动态地设置这些变量以在运行时引用正确的行为类型。

class Duck
{
private:
    QuackBehavior quackBehavior;

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

具体的子类中可以在构造函数中对quackBehavior进行初始化。

class MallardDuck: public Duck
{
public:
    MallarDuck()
    {
        quackBehavior = new Quack();
    }
}

上面的代码在构建一个具体的Quack实现类的实例,但我们通过新家setter方法仍能够在运行时动态地给它指定不同的QuackBehavior实现类。

class QuackBehavior
{
public:
    void quack() = 0;
}


class Quack: public QuackBehavior
{
public:
    void quack()
    {
        std::cout << "Quack" << std::endl;
    }
}

class Duck
{
private:
    QuackBehavior quackBehavior;

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

    void setQuackBehavior(QuackBehavior qb)
    {
        quackBehavior = qb;
    }
}

设计原则:多用组合,少用继承

策略模式:定义了算法簇,分别封装起来,让他们可以互相替换,此模式让算法的变化独立于使用算法的客户

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/608753.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode——最小化字符串长度

目录 一、题目 二、题目解读 三、代码 1、set去重 2、用一个二进制数记录每个字母是否出现过 一、题目 6462. 最小化字符串长度 - 力扣&#xff08;Leetcode&#xff09; 给你一个下标从 0 开始的字符串 s &#xff0c;重复执行下述操作 任意 次&#xff1a; 在字符串…

聊一聊数据库事务的那些事(隔离级别,传播行为)

我们平时使用事务的时候&#xff0c;可能脑子里面想到和事务有关的知识点无非就是&#xff0c;ACID&#xff0c;事务隔离级别那一套&#xff0c;使用的事务也就是是通过注解的形式&#xff0c;或者手动开启事务。更细致一点的问题或许没有深究下去&#xff0c;比如事务的传播行…

STM32F407的PWM

文章目录 32的PWM资源PWM输出原理捕获/比较模式寄存器&#xff08;TIMx_CCMR1/2&#xff09;捕获/比较使能寄存器&#xff08;TIMx_CCER&#xff09;捕获/比较寄存器&#xff08;TIMx_CCR1~4&#xff09; 库函数版本的PWM波输出开启 TIM3 时钟以及复用功能时钟置 &#xff0c;配…

对CT数据进行最小最大值归一化(Min-Max Normalization)和消除过暗过亮值处理

文章目录 PIL库的图像失真问题使用最小最大值归一化&#xff08;Min-Max Normalization&#xff09;预处理消除过暗过亮值pytorch中对tensor使用最小最大值归一化处理&#xff08;torchvision.transforms&#xff09; 我们在处理CT图像时&#xff08;以dcm格式为例&#xff09;…

全栈小程序开发路线

目录 个人心得&#xff1a; 我的学习路线 个人心得&#xff1a; 我擅长的是小程序开发和技术变现&#xff0c;从2021年至今开发上线20于个小程序&#xff0c;矩阵用户超过10万&#xff0c;变现10万左右。 以下是部分小程序截图&#xff0c;追风口做的小程序&#xff0c;基本…

「Win」Windows注册表介绍与操作

✨博客主页&#xff1a;何曾参静谧的博客 &#x1f4cc;文章专栏&#xff1a;「Win」Windows程序设计 相关术语 Windows的注册表&#xff1a;是一个重要的系统组件&#xff0c;用于存储操作系统和应用程序的配置信息。它类似于一个数据库&#xff0c;包含了各种键值对、参数、设…

Vue报错:Error: error:0308010C:digital envelope routines::unsupported解决

问题 node 环境 Node.js v18.14.2 使用npm start.出现以下报错 Error: error:0308010C:digital envelope routines::unsupported at new Hash (node:internal/crypto/hash:71:19) at Object.createHash (node:crypto:133:10) at module.exports (F:\RuoYi-Cloud\CourseSched…

SWAT模型系统学习(建模方法、实例应用、高级进阶)

目前&#xff0c;水环境问题逐渐成为制约社会经济和环境可持续发展的重要因素。根据国内外研究表明&#xff0c;受全球环境变化和经济快速发展的影响&#xff0c;面源污染已逐渐成为水环境污染的第一因素。但面源污染由于具有排放分散、隐蔽&#xff0c;排污随机、不确定、不易…

搜索算法(三) 回溯法

1.回溯法 回溯法可以理解成一种特殊的深度优先算法&#xff0c;比起普通的DFS&#xff0c;多了还原当前节点的一步。 修改当前节点、递归子节点、还原当前节点。 本质是一种试错的思想。 维基百科&#xff1a; 2.例题 1&#xff09; 力扣https://leetcode.cn/problems/pe…

树莓派安装系统

0. 实验准备 树莓派一个&#xff0c;TF卡&#xff08;4GB以上&#xff09;一个&#xff0c;读卡器一个 1. 使用官方提供的工具 在搜索引擎中搜索树莓派&#xff08;不要用百度&#xff0c;建议使用必应的国际版进行搜索&#xff09;&#xff0c;我这里直接放上树莓派官方超链…

深入篇【Linux】学习必备:理解【Linux软件包管理器】yum + yum的具体使用 + yum下载的有趣指令

这里写目录标题 Ⅰ.Linux软件包管理器yum①.什么是软件包/什么是yum②.linux的软件生态与yum源③.关于rzsz Ⅱ.yum基本指令①.查看软件②.安装软件③.卸载软件 Ⅲ.yum下载的好玩指令①.sl②.linux_logo③.elinks Ⅰ.Linux软件包管理器yum yum 是一个 Shell 前端软件包管理器。基…

C++ 多态 最详细图文+代码讲解

感谢各位 点赞 收藏 评论 三连支持 本文章收录于专栏【C进阶】 ❀希望能对大家有所帮助❀ 本文章由 风君子吖 原创 回顾 上篇文章&#xff0c;我们学习了继承的相关知识&#xff0c;详细解刨了继承中的各种细节&#xff0c;而本章内容将在继承的基础上学习多态 多态的概念…

Dreamweaver如何进行网页开发?

文章目录 0.引言1.安装Dreamweaver2.编写第一个网页 0.引言 笔者本科学习的编程语言主要是关于桌面开发的&#xff0c;对编程有一定的基础&#xff0c;而编程除了关于桌面软件开发&#xff08;VisualStudio如何进行桌面软件开发&#xff1f;&#xff09;&#xff0c;还有手机应…

网络安全自学笔记+学习路线(超详细)

01 什么是网络安全 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与防两面…

c语言编程练习题:7-193 两小时学完C语言

#include <stdio.h> int main(){int n,k,m;int sum;if (scanf("%d %d %d",&n,&k,&m)!EOF){sum n-k*m;}printf("%d",sum);return 0; }

(学习日记)2023.04.28

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

基于SSM的教务管理系统的设计与实现(论文+源码)_kaic

摘 要 学校教务管理信息化是提高办公效率的主要途径。随着中国高等教育的快速发展和学校规模的不断扩大&#xff0c;在校学生人数不断增加&#xff0c;办学层次出现多元化&#xff0c;由一地办学发展到多地多点办学&#xff0c;同时进一步推行学分制。这些变化使得教务部门的管…

【AI绘图】四、stable difusion提示词如何写?

上一篇&#xff1a;【AI绘图】三、stable diffussion操作界面介绍以及如何使用 如何写好提示词&#xff1f; 写出一份比较好的提示词是文生图技术的关键。但是&#xff0c;写出一份好的prompt并不容易&#xff0c;下面针对“如何写好提示词”这个问题&#xff0c;从提示词构成…

MySQL 数据操纵语言 DML

文章目录 数据操纵语言 DMLINSERT 语句UPDATE 语句DELETE 语句 数据操纵语言 DML 数据操纵语言&#xff08;Data Manipulation Language&#xff0c;DML&#xff09;是 SQL 语言的核心部分之一。在添加、更新或者删除表中的数据时&#xff0c;需要执行 DML 语句。很多时候我们提…