当前位置: 首页 > 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…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...