设计模式(4)--对象行为(4)--迭代器

news2024/9/27 7:15:50
1. 意图

    提供一种方法顺序访问一个聚合对象中的各个元素,而又不需暴露该对象的内部表示。

2. 四种角色

    抽象集合(Aggregate)、具体集合(Concrete Aggregate)、抽象迭代器(Iterator)、具体迭代器(Concrete Iterator)

3. 优点

    3.1 支持以不同的方式遍历一个聚合

    3.2 简化了聚合的接口

    3.3 在同一个聚合上可以有多个遍历

4. 缺点

    N/A

5. 相关模式

    5.1 迭代器常被应用到Composite这样的递归结构上。

    5.2 多态迭代器靠工厂方法来实例化适当的迭代器子类。

    5.3 迭代器内部存储一个memento,用来捕获一个迭代的状态。

6. 代码示意(C++)
#pragma once
#include <vector>
#include <string>
#include <iostream>
using namespace std;

class Employee
{
	string m_name;
public:
	Employee(const string& name) :m_name(name) {

	}
	void Print() const {
		cout << m_name << endl;
	}
};

template <class T> class Iterator;
template <class T> class ForwardIterator;

template <class T>
class Aggregate
{
	friend class ForwardIterator<T>;
public:
	virtual void Add(T data) = 0;
	virtual Iterator<T>* CreateIterator() const = 0;
private:
	virtual int Size() const = 0;
	virtual const T* Get(long pos) const = 0;
};

template <class T>
class ConcreteAggregate : public Aggregate<T>
{
	vector<T> m_vector;
	Iterator<T>* m_pIt;
public:
	ConcreteAggregate() :m_pIt(0) {
	}
	~ConcreteAggregate() {
		delete m_pIt;
	}	
	virtual void Add(T data) {
		m_vector.emplace_back(data);
	}
	//方法一:用户需负责删除
	virtual Iterator<T>* CreateIterator() const {
		return new ForwardIterator<T>(this);
	}
	//方法二:析构函数负责删除
	virtual Iterator<T>& GetIterator() {
		//先删除老的
		delete m_pIt;
		m_pIt = new ForwardIterator<T>(this);
		return *m_pIt;
	}
private:
	virtual int Size() const { return m_vector.size(); }
	virtual const T* Get(long pos) const { return &(m_vector[pos]); }
};

template <class T>
class Iterator
{
public:
	virtual void First() = 0;
	virtual void Next() = 0;
	virtual bool IsDone() const = 0;
	virtual const T* CurrentItem() const = 0;
protected:
	Iterator() {}
};

template <class T>
class ForwardIterator : public Iterator<T> {
public:
	ForwardIterator(const Aggregate<T>* pData);
	virtual void First();
	virtual void Next();
	virtual bool IsDone() const;
	virtual const T* CurrentItem() const;
private:
	const Aggregate<T>* m_pData;
	long m_current;

};
template<class T>
ForwardIterator<T>::ForwardIterator(const Aggregate<T>* pData) :m_pData(pData), m_current(0)
{
}

template<class T>
void ForwardIterator<T>::First() {
	m_current = 0;
}

template<class T>
void ForwardIterator<T>::Next() {
	++m_current;
}

template<class T>
bool ForwardIterator<T>::IsDone() const {
	return m_current >= m_pData->Size();
}

template<class T>
const T* ForwardIterator<T>::CurrentItem() const {
	if (IsDone()) {
		return 0;
	}
	return m_pData->Get(m_current);
}
#include "Iterator.h"
int main() {
	//方法一
	Aggregate<Employee>* pAggregate = new ConcreteAggregate<Employee>();
	pAggregate->Add(Employee("张三"));
	pAggregate->Add(Employee("李四"));

	Iterator<Employee>* pIt = pAggregate->CreateIterator();
	for (pIt->First(); !pIt->IsDone(); pIt->Next()) {
		pIt->CurrentItem()->Print();
	}
	cout << endl;
	delete pIt;
	delete pAggregate;

	//方法二
	ConcreteAggregate<Employee> aggregate;
	aggregate.Add(Employee("王五"));
	aggregate.Add(Employee("赵六"));

	Iterator<Employee> &it = aggregate.GetIterator();
	for (it.First(); !it.IsDone(); it.Next()) {
		it.CurrentItem()->Print();
	}

	return 0;
}

运行结果:

6.1 可以很容易实现Iterator的子类以支持不同的遍历方式(3.1)

6.2 使用方法一,可以得到多个迭代器,但用户需要负责删除迭代器指针(3.3);

       而方法二则不需要用户删除指针(也可用代理类得到相同效果) 。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

从PDF中提取图片

由于工作需要&#xff0c;要从pdf文件中提取出图片保存到本地&#xff0c;项目中就引用到了Apache PDFBox库。 1 什么是Apache PDFBox? Apache PDFBox库&#xff0c;一个用于处理PDF文档的开源Java工具。它允许用户创建全新的PDF文件&#xff0c;操作现有的PDF文档&#xff0…

Python 简易图形界面库easygui 对话框大全

easygui 安装 C:\> pip install easygui Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple Collecting easygui Using cached https://pypi.tuna.tsinghua.edu.cn/packages/8e/a7/b276ff776533b423710a285c8168b52551cb2ab0855443131fdc7fd8c16f/easygui-…

如何为你的网站启用HTTPS

步骤一&#xff1a;获取SSL/TLS证书 选择SSL证书提供商&#xff1a; 选择一家可信赖的SSL证书提供商。对于小型网站&#xff0c;JoySSL提供的免费证书是一个不错的选择。购买或申请证书&#xff1a; 根据你的网站需求&#xff0c;购买相应类型的SSL证书。证书的类型包括单域、…

电子电器架构刷写方案——General Flash Bootloader

电子电器架构刷写方案——General Flash Bootloader 我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 注&#xff1a;文章1万字左右&#xff0c;深度思考者入&#xff01;&#xff01;&#xff01; 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免…

git命令和docker命令

1、git git是分布式的版本控制工具 git可以通过本地仓库管理文件的历史版本记录 # 本地仓库操作的命令 # 初始化本地库 git init # 添加文件到暂存区 git add . git checkout 暂存区要撤销的文件名称 # 提交暂存区文件 git commit -m 注释# 版本穿梭 # 查看提交记录 git log…

Web 开发技术

Web 开发技术 | MDN (mozilla.org)https://developer.mozilla.org/zh-CN/docs/Web 开放的 Web 为开发者提供了巨大的机遇&#xff0c;为了充分利用这些技术&#xff0c;你需要知道如何使用它们。在下方你可以找到相关 Web 技术的文档链接。 面向 Web 开发者的文档 Web 开…

.halo勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复

尊敬的读者&#xff1a; 网络安全是当今数字时代的一大挑战&#xff0c;各种勒索病毒如.halo病毒层出不穷&#xff0c;对用户和企业的数据安全构成了严重威胁。本文将介绍.halo勒索病毒&#xff0c;以及如何恢复被其加密的数据文件&#xff0c;同时提供预防措施。在面对被勒索…

【MySQL基础】:超详细MySQL完整安装和配置教程

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; MySQL从入门到进阶 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言一. MySQL数据库1.1 版本1.2 下载1.3 安装1.4 客户端连接 &#x1f324;️全篇总…

IDEA基本设置

本博客适用于纯新手小白&#xff0c;或者刚下载IDEA想要优化开发添加配置的读者。 基础设置 不区分大小写代码补全 打开 IntelliJ IDEA。转到 “File”&#xff08;文件&#xff09; > “Settings”&#xff08;设置&#xff09;&#xff08;Windows/Linux&#xff09;或 “…

众和策略证券开户首选:注册制是什么意思?

注册制是什么意思&#xff1f; 注册制是指证券监管安排对在二级商场上市发行的包括股票在内的各型有价证券实施事前审理和注册的准则。 具体流程为&#xff0c;当企业或其它金融安排计划通过证券商场向大众发行股票、债券等证券时&#xff0c;需求先向监管安排提交恳求&#…

【Linux】僵尸与孤儿 进程等待

目录 一&#xff0c;僵尸进程 1&#xff0c;僵尸进程 2&#xff0c;僵尸进程的危害 二&#xff0c;孤儿进程 1&#xff0c;孤儿进程 三&#xff0c;进程等待 1&#xff0c;进程等待的必要性 2&#xff0c;wait 方法 3&#xff0c;waitpid 方法 4&#xff0c;回收小结…

基于ssm个人日常事务管理系统论文

摘 要 进入21世纪网络和计算机得到了飞速发展&#xff0c;并和生活进行了紧密的结合。目前&#xff0c;网络的运行速度以达到了千兆&#xff0c;覆盖范围更是深入到生活中的角角落落。这就促使 管理系统的发展。管理系统可以实现远程处理事务&#xff0c;远程工作信息和随时追…

基于 Python 和Surprise库,新手轻松搭建推荐系统

解密基于用户的推荐系统。 1、简介 在数据时代&#xff0c;推荐系统是提升用户体验的重要工具。今天介绍如何使用亚马逊的电影评分数据集创建电影推荐系统。 2、数据加载与探索 首先&#xff0c;通过加载和探索数据集开启数据分析过程。首先导入Pandas和Numpy&#xff0c;这…

部署Zabbix监控

一、准备环境。&#xff08;Rocky Linux release 8.9&#xff09; 1、下载rocky-linux镜像&#xff0c;部署新的虚拟机 2、查看环境是否准备成功。 [rootlocalhost ~]# cat /etc/os-release NAME"Rocky Linux" VERSION"8.9 (Green Obsidian)"二、正式安…

听GPT 讲Rust源代码--src/tools(25)

File: rust/src/tools/clippy/clippy_lints/src/methods/suspicious_command_arg_space.rs 在Rust源代码中&#xff0c;suspicious_command_arg_space.rs文件位于clippy_lints工具包的methods目录下&#xff0c;用于实现Clippy lint SUSPICIOUS_COMMAND_ARG_SPACE。 Clippy是Ru…

Linux——计算机网络基础概论

一、网络基本概念 1、定义 网络是由若干结点和连接这些结点的链路组成&#xff0c;网络中的结点可以是计算机&#xff0c;交换机、 路由器等设备。 网络设备有&#xff1a;交换机、路由器、集线器传输介质有&#xff1a;双绞线、同轴电缆、光纤连接网络的目的&#xff1a;资源…

Java多线程技术五——单例模式与多线程-备份

1 概述 本章的知识点非常重要。在单例模式与多线程技术相结合的过程中&#xff0c;我们能发现很多以前从未考虑过的问题。这些不良的程序设计如果应用在商业项目中将会带来非常大的麻烦。本章的案例也充分说明&#xff0c;线程与某些技术相结合中&#xff0c;我们要考虑的事情会…

QT 构建项目报错Could not initialize class org.codehaus.groovy.vmplugin.v7.Java7

问题 Getting NoClassDefFoundError: Could not initialize class org.codehaus.groovy.vmplugin.v7.Java7获取 NoClassDefFoundError&#xff1a;无法初始化类 org.codehaus.groovy.vmplugin.v7.Java7 解决方法一 java版本 过高 将java版本降低&#xff0c;例如从java17降…

javaweb初体验

javaweb初体验 文章目录 javaweb初体验前言一、流程&#xff1a;1.创建Maven的父工程2.创建Maven&#xff0c;Webapp的子工程3.在pom.xml文件中添加依赖&#xff08;父工程与子工程共用&#xff09;4.写一个helloservlet类实现httpservlet接口&#xff0c;重写doget&#xff0c…

生产问题(十三)谷歌Protobuf误修改系统全局时区

一、引言 最近其他组出了个线上问题&#xff0c;导致用户的时间出现问题&#xff0c;影响用户出行&#xff0c;后来才发现是谷歌的Protobuf会更改系统全局时区。不过有一说一&#xff0c;感觉jdk的问题更大。 Protobuf&#xff08;Protocol Buffers&#xff09;是一种轻量级的数…