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

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

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

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

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";}
}

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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Scala如何写一个通用的游戏数据爬虫程序

以前想要获取一些网站数据的时候&#xff0c;都是通过人工手动复制粘贴&#xff0c;这样的效率及其低下。数据少无所谓&#xff0c;如果需要采集大量数据&#xff0c;手动就显得乏力了。半夜睡不着&#xff0c;爬起来写一段有关游戏商品数据的爬虫通用模板&#xff0c;希望能帮…

Servlet实现一个简单的表白墙网站

文章目录 前言效果展示事前准备HTML、CSS、JavaScript分别负责哪些HTML和CSS构架出页面的基本结构和样式JavaScript 实现行为和交互实现服务器端的业务代码整理pom.xmlweb.xmlmessageWall.htmlMessageServlet.java 前言 前面我们学习了 Java 中知名的 HTTP 服务器 tomcat 的安…

linux下的工具---yum

一、什么是yum yum是Linux下的软件包管理器 二、什么是软件包管理器 1、在Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序. 2、但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好, 做成软件包(可以理解成windows上的安装程序)放在…

【密码学引论】Hash密码

第六章 Hash密码 md4、md5、sha系列、SM3 定义&#xff1a;将任意长度的消息映射成固定长度消息的函数功能&#xff1a;确保数据的真实性和完整性&#xff0c;主要用于认证和数字签名Hash函数的安全性&#xff1a;单向性、抗若碰撞性、抗强碰撞性生日攻击&#xff1a;对于生日…

保护您的IP地址:预防IP地址盗用的关键措施

随着互联网的发展&#xff0c;IP地址作为标识互联网设备的重要元素&#xff0c;成为网络通信的基石。然而&#xff0c;IP地址盗用威胁正不断增加&#xff0c;可能导致敏感信息泄露、未经授权的访问和网络攻击。本文将介绍一些有效的方法&#xff0c;以帮助组织和个人预防IP地址…

初学vue3与ts:路由跳转带参数

index-router <!-- 路由跳转 --> <template><div><div class"title-sub flex"><div>1、用router-link跳转带参数id1&#xff1a;</div><router-link to"./link?id1"><button>点我跳转</button>&…

scipy 笔记:scipy.spatial.distance

1 pdist 计算n维空间中观测点之间的成对距离。 scipy.spatial.distance.pdist(X, metriceuclidean, *, outNone, **kwargs) 1.1 主要参数 X一个m行n列的数组&#xff0c;表示n维空间中的m个原始观测点metric使用的距离度量out输出数组。如果非空&#xff0c;压缩的距离矩阵…

Mindomo Desktop for Mac免费思维导图软件,助您高效整理思维

思维导图是一种强大的工具&#xff0c;可以帮助我们整理思维、提高记忆力、激发创造力。而Mindomo Desktop for Mac作为一款免费的思维导图软件&#xff0c;能够帮助我们更高效地进行思维整理和项目管理。在本文中&#xff0c;我们将介绍Mindomo Desktop for Mac的功能和优势&a…

C++ day41 动态规划 整数拆分 不同的二叉搜索树

题目1&#xff1a;343 整数拆分 题目链接&#xff1a;整数拆分 对题目的理解 将正整数n&#xff0c;拆分成k个正整数的和&#xff08;k>2&#xff09;使得这些整数的乘积最大化&#xff0c;返回最大乘积 动规五部曲 1&#xff09;dp数组的含义以及其下标i的含义 dp[i]…

Linux shell编程学习笔记31:alias 和 unalias 操作 命令别名

目录 0 前言1 定义别名2 查看别名 2.1 查看所有别名2.2 查看某个别名 2.2.1 alias 别名2.2.2 alias | grep 别名字符串2.2.3 使用 CtrlAltE 组合键3 unalias&#xff1a;删除别名4 如何执行命令本身而非别名 4.1 方法1&#xff1a;使用 CtrlAltE 组合键 && unalias4…

主机的具体权限规划:ACL的使用

目的&#xff1a;针对某一用户或某一组来设置特定权限需求&#xff0c;针对上&#xff0c;接着设置 ACL可以针对单一用户&#xff0c;文件&#xff0c;或者目录来进行rwx的权限设置&#xff0c;对于需要特殊权限的设置非常有帮助。 第一&#xff0c;查看文件系统是否支持&…

YOLOv5算法进阶改进(5)— 主干网络中引入SCConv | 即插即用的空间和通道维度重构卷积

前言:Hello大家好,我是小哥谈。SCConv是一种用于减少特征冗余的卷积神经网络模块。相对于其他流行的SOTA方法,SCConv可以以更低的计算成本获得更高的准确率。它通过在空间和通道维度上进行重构,从而减少了特征图中的冗余信息。这种模块的设计可以提高卷积神经网络的性能。�…

【开源】基于JAVA的森林火灾预警系统

项目编号&#xff1a; S 019 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S019&#xff0c;文末获取源码。} 项目编号&#xff1a;S019&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 系统基础模块2.3 烟…

前五年—中国十大科技进展新闻(2012年—2017年)

前五年—中国十大科技进展新闻&#xff08;2012-2017&#xff09; 2017年中国十大科技进展新闻1. 我国科学家利用化学物质合成完整活性染色体2. 国产水下滑翔机下潜6329米刷新世界纪录3. 世界首台超越早期经典计算机的光量子计算机诞生4. 国产大型客机C919首飞5. 我国首次海域天…

02【SpringBoot静态处理、错误处理】

目录 一、SpringBoot的WEB开发 1.1 静态资源的处理 1.1.1 静态资源目录 1&#xff09;SpringBoot静态资源处理 2&#xff09;关于静态资源处理的配置 3&#xff09;欢迎页面的处理 4&#xff09;修改SpringBoot资源访问路径 1.1.2 WebJars资源 1.2 注册Servlet三大组件…

java学习part17final

110-面向对象(高级)-关键字final的使用及真题_哔哩哔哩_bilibili 1.概念 tips&#xff1a;java里有const关键字&#xff0c;但是用于保留字&#xff0c;不会使用&#xff0c;目前没有意义。 final变量没有默认赋值&#xff0c;只能在以下三个地方赋值&#xff0c;且只能赋值一…

03、K-means聚类实现步骤与基于K-means聚类的图像压缩(1)

03、K-means聚类实现步骤与基于K-means聚类的图像压缩&#xff08;1&#xff09; 03、K-means聚类实现步骤与基于K-means聚类的图像压缩&#xff08;1&#xff09; 03、K-means聚类实现步骤与基于K-means聚类的图像压缩&#xff08;2&#xff09; 开始学习机器学习啦&#xf…

【数据库】基于排序算法的去重,集合与包的并,差,交,连接操作实现原理,执行代价以及优化

基于两趟排序的其它操作 ​专栏内容&#xff1a; 手写数据库toadb 本专栏主要介绍如何从零开发&#xff0c;开发的步骤&#xff0c;以及开发过程中的涉及的原理&#xff0c;遇到的问题等&#xff0c;让大家能跟上并且可以一起开发&#xff0c;让每个需要的人成为参与者。 本专栏…

【Android】Android Framework系列--Launcher3各启动场景源码分析

Android Framework系列–Launcher3各启动场景源码分析 Launcher3启动场景 Launcher3是Android系统提供的默认桌面应用(Launcher)&#xff0c;它的源码路径在“packages/apps/Launcher3/”。 Launcher3的启动场景主要包括&#xff1a; 开机后启动&#xff1a;开机时&#xff…

【开源】基于JAVA的开放实验室管理系统

项目编号&#xff1a; S 013 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S013&#xff0c;文末获取源码。} 项目编号&#xff1a;S013&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 实验室类型模块2.2 实验室模块2.3 实…