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

【Head First 设计模式】-- 策略模式

一、背景
Head First 设计模式第一章设计模式入门–策略模式

二、工具箱的工具(本章)
1、OO基础
封装
继承
多态
抽象
2、OO原则
封装变化
面向接口编程,而非面向实现编程
组合优于继承
3、OO模式
策略模式,所谓策略模式就是定义算法族并将其分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。

算法族:白话讲就是一个对象的一组行为,但是我们通常将一组行为称之为“一族算法”。

三、例子展示
《Head First设计模式》使用鸭子举例,从一开始简单的封装实现鸭子游泳、叫的行为,到后来行为的添加之后导致现有设计的弹性不足(可复用、可扩展、可维护能力大大折扣),作者将OO基础&原则结合起来,设计一个应对鸭子行为添加时弹性较大的系统,这种模式称之为策略模式。

1、初期的鸭子系统
a.UML图
在这里插入图片描述

鸭子有游泳、叫以及展示自己品种的能力,Duck超类将swim() & quack()实现了,供子类直接调用,展示品种定义为抽象方法供子类去实现。早期看起来,采用继承的方式设计好像是没有问题的。

思考一下,当出现下面场景时现有的设计还是否合理?

如果产品要求有的鸭子是会飞的
如果产品要求并不是所有的鸭子都会叫,并且会叫的鸭子叫的方式也有可能不同
2、中期的鸭子系统
a.UML图
在这里插入图片描述

首先考虑利用接口定义行为,特殊的鸭子实现特定的接口,来达到具备某种能力的目的。这种方案,看似可行,其实对于代码的可复用性是打击性的。例如,此次需求需要实现几十种会飞的鸭子,那么我们就需要实现几十次的fly方法,这个系统几乎没有复用,成本是非常高的。

3、最终的鸭子系统
a.UML图
在这里插入图片描述

b.如何设计?
根据前面提到的设计原则:

封装变化:我们将飞行行为与呱呱叫行为都独立出来并进行了封装
面向接口编程而非实现:在Duck中,我们声明了两个变量(flyBehavior & quackBehavior),定义了两个set方法用于修改这两个变量,变量的实例是什么我不关心,我只关心我能够调用它的fly or quack这样的关键方法就行,这些方法具体是如何实现的我就不关心了
组合优于继承:在第二条中提到声明了两个变量,也就是两个变化的行为,Duck与这两个行为之间的关系是Has-a,而不是Is-a,有时候“有一个”比“是一个”更好
c.模式
而最终的这个系统运用的就是策略模式,它将算法族与使用算法的客户独立开来,可以相互替换(我可以在运行时让鸭子会叫,也可以让它不会叫)

四、代码

  1. Duck相关
    a.Duck
package com.markus.designpatterns.chapter1.duck;import com.markus.designpatterns.chapter1.behavior.FlyBehavior;
import com.markus.designpatterns.chapter1.behavior.QuackBehavior;
import com.markus.designpatterns.chapter1.behavior.concrete.FlyNoWay;
import com.markus.designpatterns.chapter1.behavior.concrete.MuteQuack;public abstract class Duck {private FlyBehavior flyBehavior;private QuackBehavior quackBehavior;public Duck() {// 默认鸭子不会飞 & 不会叫this.flyBehavior = new FlyNoWay();this.quackBehavior = new MuteQuack();}public void swim() {System.out.println("I can swim!");}abstract public void display();public void performFly(){flyBehavior.fly();}public void performQuack(){quackBehavior.quack();}public void setFlyBehavior(FlyBehavior flyBehavior) {this.flyBehavior = flyBehavior;}public void setQuackBehavior(QuackBehavior quackBehavior) {this.quackBehavior = quackBehavior;}
}

b.Duck子类

public class DecoyDuck extends Duck{@Overridepublic void display() {System.out.println("I am a Decoy Duck!");}
}
public class MallardDuck extends Duck{@Overridepublic void display() {System.out.println("I am a mallard duck!");}
}
public class RedheadDuck extends Duck{@Overridepublic void display() {System.out.println("I am a Redhead Duck!");}
}
public class RubberDuck extends Duck{@Overridepublic void display() {System.out.println("I am a Rubber Duck!");}
}

2、行为相关
a.Fly

public interface FlyBehavior {void fly();
}
public class FlyNoWay implements FlyBehavior {@Overridepublic void fly() {}
}
public class FlyWithWings implements FlyBehavior {@Overridepublic void fly() {System.out.println("I have wings, so I can fly!");}
}

b.Quack

public interface QuackBehavior {void quack();
}
public class MuteQuack implements QuackBehavior {@Overridepublic void quack() {}
}
public class Quack implements QuackBehavior {@Overridepublic void quack() {System.out.println("quack");}
}
public class Squeak implements QuackBehavior {@Overridepublic void quack() {System.out.println("squeak");}
}

3、测试Demo

public class DuckDisplayDemo {public static void main(String[] args) {Duck duck = new RedheadDuck();duck.display();duck.swim();//默认状态下不会飞、不会叫duck.performFly();duck.performQuack();System.out.println();//进行手动赋能duck.setFlyBehavior(new FlyWithWings());duck.performFly();duck.setQuackBehavior(new Quack());duck.performQuack();}
}

相关文章:

【Head First 设计模式】-- 策略模式

一、背景 Head First 设计模式第一章设计模式入门–策略模式 二、工具箱的工具(本章) 1、OO基础 封装 继承 多态 抽象 2、OO原则 封装变化 面向接口编程,而非面向实现编程 组合优于继承 3、OO模式 策略模式,所谓策略模式就是定义…...

能链智电,“重”症在身

文 | 智能相对论 作者 | 陈选滨 在过去的1-9月,充电基础设施增量为243.2万台,新能源汽车销量627.8万辆,充电桩与新能源汽车的增量比为1:2.6,距离工信部此前提出“2025年实现车桩比2:1,2030年实现车桩比1:…...

python 视频硬字幕去除 内嵌字幕去除工具 vsr

项目简介 开源地址:https://github.com/YaoFANGUK/video-subtitle-remover Video-subtitle-remover (VSR) 是一款基于AI技术,将视频中的硬字幕去除的软件。 主要实现了以下功能: 无损分辨率将视频中的硬字幕去除,生成去除字幕后…...

蓝桥等考C++组别六级004

第一部分:选择题 1、C L6 (15分) 关于switch语句,以下说法正确的是( )。 A. break语句只能用于switch语句。 B. switch语句中可以使用多个default语句。 C. switch语句中只能使用一个break语句。 D. …...

SpringBoot之Swagger

文章目录 前言一、Swagger简介二、SpringBoot集成Swagger三、配置Swagger四、配置扫描接口五、配置Swagger开关六、配置API分组七、实体配置八、常用注解 前言 作为后端开放人员,最烦的事就是自己写接口文档和别人没有写接口文档,不管是前端还是后端开发…...

抖音小店新的流量变现新时代!

随着短视频平台的日益崛起,抖音小店已成为电商领域的一股不可忽视的力量。抖音小店不仅具有极高的流量优势,还为众多商家提供了一个全新的销售渠道。那么,如何才能充分利用抖音小店的优势,打造出爆款商品,实现流量变现…...

软件架构师

软件架构师在软件开发过程中扮演着至关重要的角色,其主要职责包括: 需求分析:与用户和开发团队沟通,确定软件的需求和功能。设计架构:根据需求分析,设计软件的架构,包括系统架构、数据库架构、…...

postman接口测试

postman使用 开发中经常用postman来测试接口,一个简单的注册接口用postman测试: 接口正常工作只是最基本的要求,经常要评估接口性能,进行压力测试。 postman进行简单压力测试 下面是压测数据源,支持json和csv两个格式…...

技术分享 | web自动化测试-PageObject 设计模式

为 UI 页面写测试用例时(比如 web 页面,移动端页面),测试用例会存在大量元素和操作细节。当 UI 变化时,测试用例也要跟着变化, PageObject 很好的解决了这个问题。 使用 UI 自动化测试工具时(包…...

Mall4cloud 微服务商城系统 2.0 发布

导读现在 jdk17 和 spring boot 以及 spring cloud alibaba 2022 的第三方依赖已经趋于成熟,所以 mall4cloud 也一把梭哈做了升级嗷。 本次更新重点: 系统由 jdk8 最低要求升级到 jdk17spring boot 由 2.7.x 升级到 3.1.xjavax 升级到 jakartaspring-cl…...

SpringBoot进制转换规则问题

1.填写yml文件 dataSource:driver-class-name: com.mysql.jdbc.Driver789password: 01272.测试类 package com.forever;import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.Spri…...

12.输入一个小于1000的整数,输出平方根(不是整数,输出整数部分)

#include<stdio.h> #include<math.h>int fun(int n){int b;b pow(n,0.5);printf("%d",b);}int main(){int n;scanf("%d",&n); fun(n);return 0;}...

Django框架的推导

文章目录 Web应用简介什么是Web框架&#xff1f;什么是Web&#xff1f;应用程序的两种模式Web应用程序的优缺点 手写Web框架HTTP协议的相关知识1.四大特性2.请求数据格式3.响应数据格式 手写框架 使用wsgiref模块基于wsgiref模块搭建Web框架(最初版)基于wsgiref模块搭建Web框架…...

广东开放大学:电大搜题助力学子迎考利器

近年来&#xff0c;广东开放大学一直致力于为广大学子提供优质的教育资源和学习服务。作为一所专注于远程教育的学府&#xff0c;广东开放大学不仅拥有雄厚的师资力量和丰富的教育经验&#xff0c;还致力于创新教学手段&#xff0c;为学生提供更便捷、高效的学习体验。在这个信…...

linux 7za 编译安装

本文主要介绍了在linux下安装7z命令的方法&#xff0c;同时介绍了7z命令的使用。7z压缩格式拥有众多优点&#xff0c;具有极高的压缩比率 wget https://zenlayer.dl.sourceforge.net/project/p7zip/p7zip/16.02/p7zip_16.02_src_all.tar.bz2 tar -xjvf p7zip_16.02_src_all.ta…...

【Edge】微软Edge每次启动自动导入Chrome收藏夹,无法取消“每次启动浏览器时导入浏览数据”功能的解决方法(202311)

写在前面 Edge现在也不管用户体验了吗? 这个BUG都快一个月了&#xff0c;还没见修复&#xff0c;从118.0.2088开始&#xff0c;我是在2023年10月份一次更新后发现的这个BUG&#xff0c;结果社区论坛什么信息都没有&#xff0c;英文也没收到。 Edge的BUG现象 不知道哪次Edge…...

报错RuntimeError: no valid convolution algorithms available in CuDNN

报错信息如下RuntimeError: no valid convolution algorithms available in CuDNN 出现这个问题既不是cuda与cudnn版本不匹配&#xff0c;也不是英伟达显卡驱动需要更新&#xff01;而是因为你的显存过低不能训练&#xff0c;解决办法是使用混精度训练&#xff01;&#xff01…...

JSP通用材料收集归档系统eclipse定制开发mysql数据库BS模式java编程jdbc

一、源码特点 JSP 通用材料收集归档系统是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,eclipse开发&#xff0c;数据库为Mysql5.0&#xff0c…...

网络安全-零基础小白自学要点

1.网络安全是什么 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 2.网络安全市场 一、是市场需求量高&#xff1b; 二、则是发展相对成熟…...

SpringCloud——服务注册——Eureka

1.Eureka概述 2.Eureka架构&#xff1a; Eureka中80服务要实现对8001和8002服务访问的负载均衡&#xff0c;需要在80服务的RestTemplate上面加LoadBalanced注解&#xff0c;默认采用的是轮询的策略。 3.Eureka自我保护 当一个EurekaClient注册进EurekaServer&#xff0c;Eurek…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...

LOOI机器人的技术实现解析:从手势识别到边缘检测

LOOI机器人作为一款创新的AI硬件产品&#xff0c;通过将智能手机转变为具有情感交互能力的桌面机器人&#xff0c;展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家&#xff0c;我将全面解析LOOI的技术实现架构&#xff0c;特别是其手势识别、物体识别和环境…...

数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !

我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...

电脑桌面太单调,用Python写一个桌面小宠物应用。

下面是一个使用Python创建的简单桌面小宠物应用。这个小宠物会在桌面上游荡&#xff0c;可以响应鼠标点击&#xff0c;并且有简单的动画效果。 import tkinter as tk import random import time from PIL import Image, ImageTk import os import sysclass DesktopPet:def __i…...