设计模式——行为型模式(一)

行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配

行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。

行为型模式分为:

  • 模板方法模式
  • 策略模式
  • 命令模式
  • 职责链模式
  • 状态模式
  • 观察者模式
  • 中介者模式
  • 迭代器模式
  • 访问者模式
  • 备忘录模式
  • 解释器模式

以上 11 种行为型模式,除了模板方法模式和解释器模式是类行为型模式,其他的全部属于对象行为型模式。

6.1 模板方法模式

6.1.1 概述

在面向对象程序设计过程中,程序员常常会遇到这种情况:设计一个系统时知道了算法所需的关键步骤,而且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知,或者说某些步骤的实现与具体的环境相关。

例如,去银行办理业务一般要经过以下4个流程:取号、排队、办理具体业务、对银行工作人员进行评分等,其中取号、排队和对银行工作人员进行评分的业务对每个客户是一样的,可以在父类中实现,但是办理具体业务却因人而异,它可能是存款、取款或者转账等,可以延迟到子类中实现。

定义:

定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。

6.1.2 结构

模板方法(Template Method)模式包含以下主要角色:

  • 抽象类(Abstract Class):负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。

    • 模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法。

    • 基本方法:是实现算法各个步骤的方法,是模板方法的组成部分。基本方法又可以分为三种:

      • 抽象方法(Abstract Method) :一个抽象方法由抽象类声明、由其具体子类实现。

      • 具体方法(Concrete Method) :一个具体方法由一个抽象类或具体类声明并实现,其子类可以进行覆盖也可以直接继承。

      • 钩子方法(Hook Method) :在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种。

        一般钩子方法是用于判断的逻辑方法,这类方法名一般为isXxx,返回值类型为boolean类型。

  • 具体子类(Concrete Class):实现抽象类中所定义的抽象方法和钩子方法,它们是一个顶级逻辑的组成步骤。

6.1.3 案例实现

【例】炒菜

炒菜的步骤是固定的,分为倒油、热油、倒蔬菜、倒调料品、翻炒等步骤。现通过模板方法模式来用代码模拟。类图如下:

代码如下:

abstract class AbstractClass {
    //模板方法,为防止恶意操作,一般模板方法都加上 final 关键词。
    public final void cookProcess() {
        //第一步:倒油
        this.pourOil();
        //第二步:热油
        this.heatOil();
        //第三步:倒蔬菜
        this.pourVegetable();
        //第四步:倒调味料
        this.pourSauce();
        //第五步:翻炒
        this.fry();
    }
    public void pourOil() {
        System.out.println("倒油");
    }
    //第二步:热油是一样的,所以直接实现
    public void heatOil() {
        System.out.println("热油");
    }
    //第三步:倒蔬菜是不一样的(一个下包菜,一个是下菜心)
    public abstract void pourVegetable();
    //第四步:倒调味料是不一样
    public abstract void pourSauce();
    //第五步:翻炒是一样的,所以直接实现
    public void fry(){
        System.out.println("炒啊炒啊炒到熟啊");
    }
}
class ConcreteClass_BaoCai extends AbstractClass {
    @Override
    public void pourVegetable() {
        System.out.println("下锅的蔬菜是包菜");
    }
    @Override
    public void pourSauce() {
        System.out.println("下锅的酱料是辣椒");
    }
}
class ConcreteClass_CaiXin extends AbstractClass {
    @Override
    public void pourVegetable() {
        System.out.println("下锅的蔬菜是菜心");
    }
    @Override
    public void pourSauce() {
        System.out.println("下锅的酱料是蒜蓉");
    }
}
public class Client {
    public static void main(String[] args) {
        //炒手撕包菜
        ConcreteClass_BaoCai baoCai = new ConcreteClass_BaoCai();
        baoCai.cookProcess();
        //炒蒜蓉菜心
        ConcreteClass_CaiXin caiXin = new ConcreteClass_CaiXin();
        caiXin.cookProcess();
    }
}

倒油
热油
下锅的蔬菜是包菜
下锅的酱料是辣椒
炒啊炒啊炒到熟啊
倒油
热油
下锅的蔬菜是菜心
下锅的酱料是蒜蓉
炒啊炒啊炒到熟啊

6.1.3 优缺点

优点:

  • 提高代码复用性

    将相同部分的代码放在抽象的父类中,而将不同的代码放入不同的子类中。

  • 实现了反向控制

    通过一个父类调用其子类的操作,通过对子类的具体实现扩展不同的行为,实现了反向控制 ,并符合“开闭原则”。

缺点:

  • 对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象。
  • 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度

6.1.4 适用场景

  • 算法的整体步骤很固定,但其中个别部分易变时,这时候可以使用模板方法模式,将容易变的部分抽象出来,供子类实现。
  • 需要通过子类来决定父类算法中某个步骤是否执行,实现子类对父类的反向控制

6.2 策略模式

6.2.1 概述

先看下面的图片,我们去旅游选择出行模式有很多种,可以骑自行车、可以坐汽车、可以坐火车、可以坐飞机。

作为一个程序猿,开发需要选择一款开发工具,当然可以进行代码开发的工具有很多,可以选择Idea进行开发,也可以使用eclipse进行开发,也可以使用其他的一些开发工具。

定义:

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

6.2.2 结构

策略模式的主要角色如下:

  • 抽象策略(Strategy)类:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
  • 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现或行为。
  • 环境(Context)类:持有一个策略类的引用,最终给客户端调用。

6.2.3 案例实现

【例】促销活动

一家百货公司在定年度的促销活动。针对不同的节日(春节、中秋节、圣诞节)推出不同的促销活动,由促销员将促销活动展示给客户。类图如下:

//抽象策略类
interface Strategy {
    void show();
}
//具体策略类,为春节准备的促销活动A
class StrategyA implements Strategy {
    public void show() {
        System.out.println("买一送一");
    }
}
//为中秋准备的促销活动B
class StrategyB implements Strategy {
    public void show() {
        System.out.println("满200元减50元");
    }
}
//为圣诞准备的促销活动C
class StrategyC implements Strategy {
    public void show() {
        System.out.println("满1000元加一元换购任意200元以下商品");
    }
}
//环境类
class SalesMan {
    //持有抽象策略角色的引用
    private Strategy strategy;

    public SalesMan(Strategy strategy) {
        this.strategy = strategy;
    }

    //向客户展示促销活动
    public void salesManShow() {
        strategy.show();
    }
}
class Test {
    public static void main(String[] args) {
        Strategy strategy = new StrategyB();
        SalesMan salesMan = new SalesMan(strategy);
        salesMan.salesManShow();
    }
}

6.2.4 优缺点

1,优点:

  • 策略类之间可以自由切换

    由于策略类都实现同一个接口,所以使它们之间可以自由切换

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于JavaWeb+SSM+Vue校园水电费管理小程序系统的设计和实现

基于JavaWebSSMVue校园水电费管理小程序系统的设计和实现 源码获取入口Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 Lun文目录 摘 要 III Abstract 1 1 系统概述 2 1.1 概述 2 1.2课题意义 3 1.3 主要内容 3…

easyrecovery免费版2024最新电脑数据恢复工具

easyrecovery免费版是一款操作简便且实用的数据恢复工具,easyrecovery绿色版可以用来恢复各种各样被删除的文件、视频、图片等;EasyRecovery功能非常全面,easyrecovery还可以支持SD卡数据恢复,TF卡等各种存储卡文件恢复(图片、视频…

【无标题】学习HTML

由于工作需求,学习了一些html的相关知识,最终应用到打印功能上使用。 HTML是指超文本标记语言(HyperText Markup Language)。它是一种用于创建和呈现互联网上页面的标准标记语言。HTML是Web开发的基础,是构建网页和应…

掌握未来技术趋势,成为领先者——深度解析2023年技术热点

掌握未来技术趋势,成为领先者——深度解析2023年技术热点 摘要:本文探讨当前最热门的技术趋势。我们将介绍人工智能、大数据、区块链、5G等前沿技术,并阐述它们如何改变我们的生活。最后,我们将总结如何利用这些技术趋势&#xf…

中断方式的数据接收

中断接收简介 回顾之前的代码 之前的代码是 等待标志位RXNE位为1才有数据 进而读取数据存放在变量c中 再根据c变量的数据是为0还是为1进而编写灯亮灭的代码 if语句 但这样的代码明显不符合裸机多任务的编程模型 因为在while中为进程 进程执行的时间不能大于5ms 但是while&…

pcie-2-rj45速度优化

背景: 目前用iperf3打流传输速率达不到要求,千兆实际要求跑到800M以上: 优化方案: 1.优化defconfig: 首先编译user版本验证看是否正常 debug版本关闭CONFIG_SLUB_DEBUG_ON宏控。 2.找FAE ,通过更换驱动,或者更新驱动来优化 3.绑定大核: 以8125网卡为例,udp…

企业数字化转型的作用是什么?_光点科技

在当今快速变化的商业环境中,数字化转型已成为企业发展的重要策略。企业数字化转型指的是利用数字技术改造传统业务模式和管理方式,以提升效率、增强竞争力和创造新的增长机会。 提升运营效率:数字化转型通过引入自动化工具和智能系统&#x…

【数据结构】树如何定义 | 如何存储 | 实际应用

前言 如上图,A中的孩子的个数是不固定的。我们无法精确的每个不同的根结点有多少个孩子。所以并不能精确知道需要定义多少个孩子节点。 struct TreeNode {int val;struct TreeNode* child1;struct TreeNode* child2;struct TreeNode* child3;//...//这样显然是不能…

AnalyticDB for PostgreSQL 实时数据仓库上手指南

AnalyticDB for PostgreSQL 实时数据仓库上手指南 2019-04-016601 版权 本文涉及的产品 云原生数据仓库 ADB PostgreSQL,4核16G 50GB 1个月 推荐场景: 构建的企业专属Chatbot 立即试用 简介: AnalyticDB for PostgreSQL 提供企业级数…

mysql 行转列 GROUP_CONCAT 试验

1.概要 很多时候需要用到行专列的方式做数据分析。比如对通讯数据的采集 数据采集结果如下: 变量值采集周期131251132272 我想要看的结果 变量1变量2采集周期351372 就是我想看到相关数据的周期变化情况。 2.试验 2.1创建数据如下(表名 tb5&…

CentOS虚拟机重置账号密码

虚拟机忘记密码了 一般来说,虚拟机的账号密码,工作中都会有文档记录,如果忘记了可以查看文档。但是也有特例,虚拟机的密码没有记录到文档中,尝试了很多次依然登录失败,这时候就只能重置账号密码了。 1.重…

使用vcpkg安装库失败的解决方法

1、前言 vcpk是是一款开源的c/c库管理工具,尤其是在windows平台,可以帮助我们很好的管理各种依赖包。 在windows环境做c/c开发的人应该都深有体会,有时候编译需要下载一堆依赖库,导致搭建编译环境特别麻烦。但是,通过v…

【黑马甄选离线数仓day02_数据采集】

1. 数仓工具使用-DataX 1.1 DataX介绍 ​ DataX 是阿里推出的一个异构数据源离线同步工具,致力于实现包括关系型数据库(MySQL、Oracle等)、HDFS、Hive、ODPS、HBase、FTP等各种异构数据源之间稳定高效的数据同步功能。 ​ 将DataX安装好之后, 仅需要配置Json的采…

STM32 中断系统

单片机学习 目录 文章目录 前言 一、中断系统 1.1 什么是中断 1.2 中断优先级 1.3 中断嵌套 1.4 C语言中的中断程序 二、STM32的中断通道和中断向量 2.1 中断通道 2.2 嵌套向量中断控制器NVIC 2.2.1 什么是NVIC 2.2.2 NVIC基本结构 2.2.3抢占优先级和响应优先级 2.2.4 NVIC的优…

【OJ比赛日历】快周末了,不来一场比赛吗? #11.25-12.01 #17场

CompHub[1] 实时聚合多平台的数据类(Kaggle、天池…)和OJ类(Leetcode、牛客…)比赛。本账号会推送最新的比赛消息,欢迎关注! 以下信息仅供参考,以比赛官网为准 目录 2023-11-25(周六) #9场比赛2023-11-26…

分布式链路追踪入门篇-基础原理与快速应用

为什么需要链路追踪? 我们程序员在日常工作中,最常做事情之一就是修bug了。如果程序只是运行在单机上,我们最常用的方式就是在程序上打日志,然后程序运行的过程中将日志输出到文件上,然后我们根据日志去推断程序是哪一…

Selenium介绍及基本使用方法

Selenium是一个开源、免费、简单、灵活,对Web浏览器支持良好的自动化测试工具,在UI自动化、爬虫等场景下是十分实用的,能够熟练掌握并使用Selenium工具可以大大的提高效率。 Selenium简介 Selenium支持多平台、多浏览器、多语言去实现自动化…

为销售赋能:利用 Splashtop 增强远程培训技术

远程销售团队这一概念在当今快节奏的商业环境中日益普遍。各公司正在计划在不同地点灵活开展销售业务,希望利用技术优势缩小地域差距。但是,这种向远程销售的转型面临着重大挑战,尤其在培训和发展领域。培训远程销售团队需要采用创新方法&…

Kafka 控制器(controller)

Kafka 控制器(controller) 在kafka集群中 会存在一个或者多个broker(一个服务器就是一个broker),其中有一个broker会被选举为控制器 kafka controller ,负责管理整个集群中所有副本、分区的状态&#xff0…

5.1 PBR基础 BRDF介绍

基于物理的渲染(Physically Based Rendering,PBR)是指使用基于物理原理和微平面理论建模的着色/光照模型,以及使用从现实中测量的表面参数来准确表示真实世界材质的渲染理念。 一、反射率方程 理论基础放在参考链接里。 直接开始…