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

设计模式之十二:复合模式

模式通常被一起使用,并被组合在同一个解决方案中。

复合模式在一个解决方案中结合两个或多个模式,以解决一般或重复发生的问题。

首先重新构建鸭子模拟器:

package headfirst.designpatterns.combining.ducks;public interface Quackable {public void quack();
}public class MallardDuck implements Quackable {public void quack() {System.out.println("Quack");}
}public class RubberDuck implements Quackable {public void quack() {System.out.println("Squeak");}
}
package headfirst.designpatterns.combining.ducks;public class DuckSimulator {public static void main(String[] args) {DuckSimulator simulator = new DuckSimulator();simulator.simulate();}void simulate() {Quackable mallardDuck = new MallardDuck();Quackable redheadDuck = new RedheadDuck();Quackable duckCall = new DuckCall();Quackable rubberDuck = new RubberDuck();System.out.println("\nDuck Simulator");simulate(mallardDuck);simulate(redheadDuck);simulate(duckCall);simulate(rubberDuck);}void simulate(Quackable duck) {duck.quack();}
}

需求1,有鸭子的地方大概率就会有鹅,怎样在模拟器使用鹅呢?适配器

package headfirst.designpatterns.combining.adapter;public class Goose {public void honk() {System.out.println("Honk");}
}
package headfirst.designpatterns.combining.adapter;public class GooseAdapter implements Quackable {Goose goose;public GooseAdapter(Goose goose) {this.goose = goose;}public void quack() {goose.honk();}public String toString() {return "Goose pretending to be a Duck";}
}

需求2,如果在不变化鸭子类的情况下,计算呱呱叫的次数呢?装饰者

将鸭子包装进装饰者对象,赋予鸭子一些新行为。

package headfirst.designpatterns.combining.decorator;public class QuackCounter implements Quackable {Quackable duck;static int numberOfQuacks;public QuackCounter (Quackable duck) {this.duck = duck;}public void quack() {duck.quack();numberOfQuacks++;}public static int getQuacks() {return numberOfQuacks;}public String toString() {return duck.toString();}
}
// 更新模拟器Quackable mallardDuck = new QuackCounter(new MallardDuck());

需求3,有时候我们在代码中可能搞忘装饰对象,所以我们希望在最开始创建的时候就确保鸭子是被装饰过的:工厂模式

package headfirst.designpatterns.combining.factory;public abstract class AbstractDuckFactory {public abstract Quackable createMallardDuck();public abstract Quackable createRedheadDuck();public abstract Quackable createDuckCall();public abstract Quackable createRubberDuck();
}
package headfirst.designpatterns.combining.factory;public class CountingDuckFactory extends AbstractDuckFactory {public Quackable createMallardDuck() {return new QuackCounter(new MallardDuck());}public Quackable createRedheadDuck() {return new QuackCounter(new RedheadDuck());}public Quackable createDuckCall() {return new QuackCounter(new DuckCall());}public Quackable createRubberDuck() {return new QuackCounter(new RubberDuck());}
}

抽象工厂通过传入不同的工厂到创建方法中,得到不同的产品家族。

package headfirst.designpatterns.combining.factory;public class DuckSimulator {public static void main(String[] args) {DuckSimulator simulator = new DuckSimulator();AbstractDuckFactory duckFactory = new CountingDuckFactory();simulator.simulate(duckFactory);}void simulate(AbstractDuckFactory duckFactory) {Quackable mallardDuck = duckFactory.createMallardDuck();Quackable redheadDuck = duckFactory.createRedheadDuck();Quackable duckCall = duckFactory.createDuckCall();Quackable rubberDuck = duckFactory.createRubberDuck();Quackable gooseDuck = new GooseAdapter(new Goose());System.out.println("\nDuck Simulator: With Abstract Factory");simulate(mallardDuck);simulate(redheadDuck);simulate(duckCall);simulate(rubberDuck);simulate(gooseDuck);System.out.println("The ducks quacked " + QuackCounter.getQuacks() + " times");}void simulate(Quackable duck) {duck.quack();}
}

需求4,同时管理一群鸭子:组合模式

package headfirst.designpatterns.combining.composite;import java.util.Iterator;
import java.util.ArrayList;public class Flock implements Quackable {ArrayList<Quackable> quackers = new ArrayList<Quackable>();public void add(Quackable quacker) {quackers.add(quacker);}public void quack() {Iterator<Quackable> iterator = quackers.iterator();while (iterator.hasNext()) {Quackable quacker = iterator.next();quacker.quack();}}public String toString() {return "Flock of Quackers";}
}
package headfirst.designpatterns.combining.composite;public class DuckSimulator {public static void main(String[] args) {DuckSimulator simulator = new DuckSimulator();AbstractDuckFactory duckFactory = new CountingDuckFactory();simulator.simulate(duckFactory);}void simulate(AbstractDuckFactory duckFactory) {Quackable redheadDuck = duckFactory.createRedheadDuck();Quackable duckCall = duckFactory.createDuckCall();Quackable rubberDuck = duckFactory.createRubberDuck();Quackable gooseDuck = new GooseAdapter(new Goose());System.out.println("\nDuck Simulator: With Composite - Flocks");Flock flockOfDucks = new Flock();flockOfDucks.add(redheadDuck);flockOfDucks.add(duckCall);flockOfDucks.add(rubberDuck);flockOfDucks.add(gooseDuck);Flock flockOfMallards = new Flock();Quackable mallardOne = duckFactory.createMallardDuck();Quackable mallardTwo = duckFactory.createMallardDuck();Quackable mallardThree = duckFactory.createMallardDuck();Quackable mallardFour = duckFactory.createMallardDuck();flockOfMallards.add(mallardOne);flockOfMallards.add(mallardTwo);flockOfMallards.add(mallardThree);flockOfMallards.add(mallardFour);flockOfDucks.add(flockOfMallards);System.out.println("\nDuck Simulator: Whole Flock Simulation");simulate(flockOfDucks);System.out.println("\nDuck Simulator: Mallard Flock Simulation");simulate(flockOfMallards);System.out.println("\nThe ducks quacked " + QuackCounter.getQuacks() + " times");}void simulate(Quackable duck) {duck.quack();}
}

需求5,持续追踪个别鸭子的实时呱呱叫:观察者模式

package headfirst.designpatterns.combining.observer;public interface QuackObservable {public void registerObserver(Observer observer);public void notifyObservers();
}public interface Quackable extends QuackObservable {public void quack();
}

现在需要保证Quackable的具体类都能扮演QuackObservable角色(在具体类中添加一个arraylist变量,然后实现接口方法)。但这里用的不同的做法(不知道为什么),在Observable类中封装注册和通知的代码,然后将其和具体类组合在一起。

package headfirst.designpatterns.combining.observer;import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;public class Observable implements QuackObservable {List<Observer> observers = new ArrayList<Observer>();QuackObservable duck;public Observable(QuackObservable duck) {this.duck = duck;}public void registerObserver(Observer observer) {observers.add(observer);}public void notifyObservers() {Iterator<Observer> iterator = observers.iterator();while (iterator.hasNext()) {Observer observer = iterator.next();observer.update(duck);}}public Iterator<Observer> getObservers() {return observers.iterator();}
}
package headfirst.designpatterns.combining.observer;public class MallardDuck implements Quackable {Observable observable;public MallardDuck() {observable = new Observable(this);}public void quack() {System.out.println("Quack");notifyObservers();}public void registerObserver(Observer observer) {observable.registerObserver(observer);}public void notifyObservers() {observable.notifyObservers();}public String toString() {return "Mallard Duck";}
}

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

相关文章:

设计模式之十二:复合模式

模式通常被一起使用&#xff0c;并被组合在同一个解决方案中。 复合模式在一个解决方案中结合两个或多个模式&#xff0c;以解决一般或重复发生的问题。 首先重新构建鸭子模拟器&#xff1a; package headfirst.designpatterns.combining.ducks;public interface Quackable …...

java通过年月获取当前月所有周(跨月),获取每周开始日期和结束日期

/*** 根据年月返回本月共几周&#xff0c;每周开始与结束日期*/public static List<Map<String, String>> queryWeek(String year, String month) throws ParseException {/** 周 **/final String[] weeks { "第一周", "第二周", "第…...

9.3 Windows驱动开发:内核解析PE结构节表

在笔者上一篇文章《内核解析PE结构导出表》介绍了如何解析内存导出表结构&#xff0c;本章将继续延申实现解析PE结构的PE头&#xff0c;PE节表等数据&#xff0c;总体而言内核中解析PE结构与应用层没什么不同&#xff0c;在上一篇文章中LyShark封装实现了KernelMapFile()内存映…...

Zephyr:Direct Distillation of LM Alignment

Zephyr&#xff1a;Direct Distillation ofLM Alignment IntroductionMethod Introduction dSFT已经被可以提升模型的指令遵循能力的准确性&#xff0c;但是student model 不会超过 teacher model。 作者认为 dSFT虽然可以让模型更好的理解用户意图&#xff0c;但是无法与人类…...

二叉树--算法题总结

1、利用层序遍历的产生的字符串来创建二叉树 /*** 使用层序遍历的字符串创建二叉树* param treeInfo* return*/public static TreeNode generateTreeNodeSecond(String treeInfo) {LinkedList<TreeNode> treeNodeLinkedList new LinkedList<>();if(StringUtils.is…...

PyQt6 QLabel标签控件

​锋哥原创的PyQt6视频教程&#xff1a; 2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~共计21条视频&#xff0c;包括&#xff1a;2024版 PyQt6 Python桌面开发 视频教程(无废话…...

即时通讯技术文集(第24期):音视频WebRTC好文合集 [共20篇]

为了更好地分类阅读 52im.net 总计1000多篇精编文章&#xff0c;我将在每周三推送新的一期技术文集&#xff0c;本次是第 24 期。 [- 1 -] 开源实时音视频技术WebRTC的现状 [链接] http://www.52im.net/article-126-1.html [摘要] 作为Google开源的技术&#xff0c;WebRTC并不…...

HTML+CSS+JS网页设计与制作摄影类个人网页

可以使用网页三剑客htmlcssjs实现网页设计与制作&#xff0c;页面排版布局高端大气。 使用HTMLCSS页面布局设计&#xff0c;HTMLCSSJS网页设计与制作摄影类个人网页&#xff0c;这是一个优质的个人网页制作。 凭借简约的设计风格、精湛的制作工艺&#xff0c;突破与创新的理念…...

U-boot(五):启动内核

本文主要探讨210的uboot启动内核过程。 嵌入式系统状态启动 未上电时bootloader、kernel、rootfs以镜像形式存储在启动介质中(X210为iNand/SD卡),运行时搬运到DDR中 未上电时u-boot.bin,zImage,rootfs在SD卡中各自对应的分区中,启动时去对应分区寻找(分区表一…...

tp8 使用rabbitMQ(2)工作队列

代码的参数说明在 第一小节的代码中&#xff0c;如果需要可移步到第一节中查看 工作队列 工作队列&#xff08;又称&#xff1a;任务队列——Task Queues&#xff09;是为了避免等待一些占用大量资源、时间的操作。当我们把任务&#xff08;Task&#xff09;当作消息发送到队列…...

ZKP11.4 Use CI to instantiate Fiat-Shamir

ZKP学习笔记 ZK-Learning MOOC课程笔记 Lecture 11: From Practice to Theory (Guest Lecturer: Alex Lombardi) 11.4 Use CI to instantiate Fiat-Shamir Avoid Bad Challenges Def: Given false claim x x x and a first message α \alpha α, a challenge β \beta …...

华为云编译构建CodeArts Build常见问答汇总

1.【Build】公有云编译构建是否支持导入外部机器做执行机 答&#xff1a;参考链接&#xff1a;https://support.huaweicloud.com/usermanual-devcloud/devcloud_01_0017.html • 使用代理机功能&#xff0c;需要配备1台4U8G或以上规格、磁盘>80GB的主机。 • 安装代理的…...

009 OpenCV 二值化 threshold

一、环境 本文使用环境为&#xff1a; Windows10Python 3.9.17opencv-python 4.8.0.74 二、二值化算法 2.1、概述 在机器视觉应用中&#xff0c;OpenCV的二值化函数threshold具有不可忽视的作用。主要的功能是将一幅灰度图进行二值化处理&#xff0c;以此大幅降低图像的数…...

基于python的NBA球员数据可视化分析的设计与实现

完整下载&#xff1a;基于python的NBA球员数据可视化分析的设计与实现.docx 基于python的NBA球员数据可视化分析的设计与实现 Design and Implementation of NBA Player Data Visualization Analysis based on Python 目录 目录 2 摘要 3 关键词 4 第一章 引言 4 1.1 研究背景 …...

《使用Python将Excel数据批量写入MongoDB数据库》

在数据分析及处理过程中&#xff0c;我们经常需要将数据写入数据库。而MongoDB作为一种NoSQL数据库&#xff0c;其具有强大的可扩展性、高性能以及支持复杂查询等特性&#xff0c;广泛用于大规模数据存储和分析。在这篇文章中&#xff0c;我们将使用Python编写一个将Excel数据批…...

leetcode_828_统计子串中的唯一字符

题意&#xff1a;所有子串中单个字符出现的次数和 问题转化&#xff1a;对于串中的每个字符&#xff0c;只包含其一次的所有子串的个数和 关于求只包含某位置字符一次的子串个数 class Solution { public:int uniqueLetterString(string s) {/* ...A...A...A...*/int n s.size…...

「Java开发中文指南」IntelliJ IDEA插件安装(一)

IntelliJ IDEA是java编程语言开发的集成环境。IntelliJ在业界被公认为最好的Java开发工具&#xff0c;尤其在智能代码助手、代码自动提示、重构、JavaEE支持、各类版本工具(git、svn等)、JUnit、CVS整合、代码分析、 创新的GUI设计等方面的功能是非常强大的。 插件扩展了Intel…...

单机多卡训练

参考几个不错的帖子&#xff08;还没来得及整理&#xff09;&#xff1a; 基于pytorch多GPU单机多卡训练实践_多卡训练效果不如单卡-CSDN博客 关于PyTorch单机多卡训练_能用torch.device()实现多卡训练吗-CSDN博客 Pytorch多机多卡分布式训练 - 知乎 (zhihu.com) 当代研究生…...

数据库基础教程之数据库的创建(一)

双击打开Navicat&#xff0c;点击&#xff1a;文件-》新建连接-》PostgreSQL 在下图新建连接中输入各参数&#xff0c;然后点击&#xff1a;连接测试&#xff0c;连接成功后再点击确定。 点击新建数据库 数据库设置如下&#xff1a;...

Python教程:DataFrame列数据类型的转换

Pandas提供了多种数据类型转换方法。可以使用astype()函数来转换数据类型。例如&#xff0c;可以将字符串类型的列转换为整数类型的列&#xff1a; # Author : 小红牛 # 微信公众号&#xff1a;wdPython import pandas as pd# 创建包含字符串类型列的DataFrame df pd.DataFra…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

C++:多态机制详解

目录 一. 多态的概念 1.静态多态&#xff08;编译时多态&#xff09; 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1&#xff09;.协变 2&#xff09;.析构函数的重写 5.override 和 final关键字 1&#…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

逻辑回归暴力训练预测金融欺诈

简述 「使用逻辑回归暴力预测金融欺诈&#xff0c;并不断增加特征维度持续测试」的做法&#xff0c;体现了一种逐步建模与迭代验证的实验思路&#xff0c;在金融欺诈检测中非常有价值&#xff0c;本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...

关于easyexcel动态下拉选问题处理

前些日子突然碰到一个问题&#xff0c;说是客户的导入文件模版想支持部分导入内容的下拉选&#xff0c;于是我就找了easyexcel官网寻找解决方案&#xff0c;并没有找到合适的方案&#xff0c;没办法只能自己动手并分享出来&#xff0c;针对Java生成Excel下拉菜单时因选项过多导…...

9-Oracle 23 ai Vector Search 特性 知识准备

很多小伙伴是不是参加了 免费认证课程&#xff08;限时至2025/5/15&#xff09; Oracle AI Vector Search 1Z0-184-25考试&#xff0c;都顺利拿到certified了没。 各行各业的AI 大模型的到来&#xff0c;传统的数据库中的SQL还能不能打&#xff0c;结构化和非结构的话数据如何和…...

SQL进阶之旅 Day 22:批处理与游标优化

【SQL进阶之旅 Day 22】批处理与游标优化 文章简述&#xff08;300字左右&#xff09; 在数据库开发中&#xff0c;面对大量数据的处理任务时&#xff0c;单条SQL语句往往无法满足性能需求。本篇文章聚焦“批处理与游标优化”&#xff0c;深入探讨如何通过批量操作和游标技术提…...