设计模式入门:策略模式

news/2024/11/7 12:36:42/

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

每种鸭子都会呱呱叫和游泳,只是外观不同。因此,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.ppmy.cn/news/211200.html

相关文章

条码软件如何制作GS1-128条形码

GS1是国际物品编码组织的英文名称&#xff0c;全称为GS1全球统一标识系统。GS1是整个一个系统&#xff0c;或者说架构&#xff0c;其架构内部所包含的条码&#xff0c;可以有很多种&#xff0c;比如内部的条码是Code 128的&#xff0c;叫做GS1-128&#xff0c;而内部是DataBar的…

亚马逊条码标签(SSCC/FBA)的制作打印

近日&#xff0c;亚马逊对所有商家提出统一要求&#xff0c;产品须按照亚马逊制定的新规范来打印条码标签。做亚马逊外贸的商户都清楚&#xff0c;货品进入亚马逊仓库都必须通过扫描入库&#xff0c;否则无法进行上市销售。 有很多客户最近联系我们请求提供技术指导&#xff0c…

条码标签软件快速生成序列号标签

在做条码标签的时候&#xff0c;各行各业应该都会制作一种可变数据标签——序列号标签。其实输入序列号很简单&#xff0c;如果数量不多&#xff0c;手工输入都是可以的&#xff0c;可是如果需要100个、1000个、甚至10000个序列号的时候&#xff0c;难道还手工输入吗&#xff1…

gt800打印测试软件,zebra GT800 高级桌面条码标签打印机

zebra GT800 高级桌面条码标签打印机 zebra GT800 热敏/热传印桌面标签打印机以极具竞争优势的价格实现了先进性能和可靠性&#xff0c;提供一系列功能&#xff0c;可满足各类中、低容量的打印应用。GT800 能容纳 300 米碳带&#xff0c;增加了灵活性和打印机正常运行时间&…

条码标签里的数据源如何使用

很多小伙伴在刚开始使用条码软件制作标签时&#xff0c;会对于数据源这个概念有些陌生&#xff0c;也不知道该在什么时候使用数据源。其实这个很好判断&#xff0c;基本宗旨就是如果一个元素是固定不变的&#xff0c;那么就不需要使用数据源&#xff0c;如果一个元素的内容是变…

使用普通打印机打印条码标签

条码标签不仅可以在专用的标签打印机上打印&#xff0c;也可以在普通打印机上打印&#xff0c;我们只需要设计好一个标签的内容&#xff0c;然后排版&#xff0c;最后选择普通打印机即可。下面小编用一个例子来演示操作步骤。 首先我们打开条码标签软件&#xff0c;新建一个条…

如何使用hiprint插件制作条码标签

hiprint中文网址&#xff1a;http://www.hinnn.com/ 模板设计地址&#xff1a;http://www.hinnn.com/design 使用比较方便&#xff0c;可以在线设计模板&#xff0c;并且预览。 在记录一下如何制作二维码&#xff0c;久了不用也容易忘记。 下面是制作出来的模板示例图&#xff…

java打印标签(机型TOSHIBA条码打印机B-EX4T)

java打印标签 实现方式标签效果代码获取更多相关资料实现rfid写入功能&#xff1a; 实现方式 打印机设置网络ip java获取socket连接&#xff0c;调用TPCL指令 标签效果 代码 package org.jeecg.modules.invinfo.util;import org.jeecg.modules.invinfo.vo.BatKcInventoryDet…