【設計模式】迭代器模式 (游標(Cursor)模式)

迭代器模式(Iterator Pattern)詳解


一、迭代器模式簡介

迭代器模式(Iterator Pattern) 是一種 行為型設計模式(對象行為型模式),它提供了一種方法來順序訪問一個聚合對象中的各個元素,而無需暴露該對象的內部表示。換句話說,迭代器模式使得客戶端可以通過統一的方式來遍歷不同的集合類型(如數組、鏈表等),同時不需要了解這些集合的內部結構。

你可以把它想象成電視遙控器上的“下一個頻道”按鈕,無論你當前在觀看哪個頻道,按下這個按鈕都會帶你去到下一個頻道,而你并不需要知道電視臺是如何排列這些頻道的。

在這里插入圖片描述
電視機 <- -> 存儲電視頻道的集合 <- -> 聚合類(Aggregate Classes)
電視機遙控器 <- -> 操作電視頻道 <- -> 迭代器(Iterator)
訪問一個聚合對象中的元素但又不需要暴露它的內部結構

聚合對象的兩個職責

  1. 存儲數據,聚合對象的基本職責
  2. 遍歷數據,既是可變化的,又是可分離的

將遍歷數據的行為從聚合對象中分離出來,封裝在迭代器對象中
由迭代器來提供遍歷聚合對象內部數據的行為,簡化聚合對象的設計,更符合單一職責原則

迭代器模式:提供一種方法順序訪問一個聚合對象中各個元素,且不用暴露該對象的內部表示。

又名**游標(Cursor)**模式。

通過引入迭代器,客戶端無須了解聚合對象的內部結構即可實現對聚合對象中成員的遍歷,還可以根據需要很方便地增加新的遍歷方式。

迭代器模式包含以下4個角色

Iterator(抽象迭代器)
ConcreteIterator(具體迭代器)
Aggregate(抽象聚合類)
ConcreteAggregate(具體聚合類)

在這里插入圖片描述


二、解決的問題類型

迭代器模式主要用于解決以下問題:

  • 不同數據結構的遍歷方式不一致:比如數組和鏈表有不同的遍歷方式。
  • 希望隱藏容器的內部實現細節:使客戶端代碼與具體的容器實現解耦。
  • 支持多種遍歷方式:例如前序遍歷、中序遍歷、后序遍歷等。
  • 為遍歷不同的聚合結構提供一個統一的接口:在該接口的實現類中為不同的聚合結構提供不同的遍歷方式,而客戶端可以一致性地操作該接口。
  • 訪問一個聚合對象的內容而無須暴露它的內部表示

三、使用場景

場景示例
集合類庫Java 的 ArrayList, HashSet 等都實現了 Iterable 接口
自定義集合類當你需要為自定義的數據結構提供遍歷功能時
復雜數據結構如樹形結構或圖結構

四、核心概念

  1. Iterator(迭代器接口):定義了遍歷操作的方法,如 hasNext(), next(), 和可選的 remove()
  2. ConcreteIterator(具體迭代器):實現了 Iterator 接口,負責管理當前遍歷的位置。
  3. Aggregate(聚合接口):定義了創建迭代器對象的方法 createIterator()
  4. ConcreteAggregate(具體聚合類):實現了 Aggregate 接口,返回一個 ConcreteIterator 實例。

五、實際代碼案例(Java)

1. 定義 Iterator 接口

// 迭代器接口
public interface Iterator<T> {boolean hasNext();T next();
}

2. 定義 ConcreteIterator 類

// 具體迭代器類
class NameIterator implements Iterator<String> {private String[] names;private int position = 0;public NameIterator(String[] names) {this.names = names;}@Overridepublic boolean hasNext() {return position < names.length;}@Overridepublic String next() {if (this.hasNext()) {return names[position++];} else {return null;}}
}

3. 定義 Aggregate 接口

// 聚合接口
public interface Aggregate {Iterator createIterator();
}

4. 定義 ConcreteAggregate 類

// 具體聚合類
class NameCollection implements Aggregate {private String[] names;public NameCollection(String[] names) {this.names = names;}@Overridepublic Iterator createIterator() {return new NameIterator(names);}
}

5. 客戶端測試類

public class Client {public static void main(String[] args) {String[] names = {"Alice", "Bob", "Charlie"};Aggregate collection = new NameCollection(names);Iterator iterator = collection.createIterator();while (iterator.hasNext()) {System.out.println(iterator.next());}}
}

輸出結果:

Alice
Bob
Charlie
典型代碼

典型的抽象迭代器代碼

interface Iterator
{void First(); //將游標指向第一個元素void Next(); //將游標指向下一個元素bool HasNext(); //判斷是否存在下一個元素object CurrentItem(); //獲取游標指向的當前元素
}

典型的具體迭代器代碼

class ConcreteIterator : Iterator
{private ConcreteAggregate objects; //維持一個對具體聚合對象的引用,以便于訪問存儲在聚合對象中的數據private int cursor; //定義一個游標,用于記錄當前訪問位置public ConcreteIterator(ConcreteAggregate objects) {this.objects = objects;}public void First() {  //實現代碼  }	public void Next() { //實現代碼  }public bool HasNext() {  //實現代碼}	public object CurrentItem(){  //實現代碼}
}

典型的抽象聚合類代碼

interface Aggregate
{Iterator CreateIterator();
}

典型的具體聚合類代碼

class ConcreteAggregate : Aggregate 
{......public Iterator CreateIterator() {return new ConcreteIterator(this);}......
}
其他案例
  1. 某軟件公司為某商場開發了一套銷售管理系統,在對該系統進行分析
    AbstractObjectList類的方法與說明
    在這里插入圖片描述
    AbstractObjectList類的子類ProductList和CustomerList分別用于存儲商品數據和客戶數據。
    通過分析,發現AbstractObjectList類的職責非常重,它既負責存儲和管理數據,又負責遍歷數據,違背了單一職責原則,實現代碼將非常復雜。因此,開發人員決定使用迭代器模式對AbstractObjectList類進行重構,將負責遍歷數據的方法提取出來,封裝到專門的類中,實現數據存儲和數據遍歷分離,還可以給不同的具體數據集合類提供不同的遍歷方式。
    現給出使用迭代器模式重構后的解決方案。

在這里插入圖片描述

  1. 電視機遙控器
    電視機遙控器就是一個迭代器的實例,通過它可以實現對電視機頻道集合的遍歷操作,本實例我們將模擬電視機遙控器的實現。

在這里插入圖片描述


六、優缺點分析

優點描述
? 簡化了集合的遍歷過程提供了一致的遍歷接口,便于維護和擴展,
? 封裝性良好隱藏了集合的內部結構,增強了安全性,簡化了聚合類
? 支持多種遍歷方式可以為同一集合提供不同的迭代器實現,在同一個聚合對象上可以定義多種遍歷方式
其他由于引入了抽象層,增加新的聚合類和迭代器類都很方便,無須修改原有代碼,符合開閉原則
缺點描述
? 增加了系統復雜度對于簡單的集合遍歷需求,引入迭代器模式可能顯得過于復雜。在增加新的聚合類時需要對應地增加新的迭代器類,類的個數成對增加。
? 性能開銷創建迭代器實例會帶來額外的內存消耗
其他抽象迭代器的設計難度較大,需要充分考慮到系統將來的擴展。在自定義迭代器時,創建一個考慮全面的抽象迭代器并不是一件很容易的事情

七、與其他模式對比(補充)

模式名稱目標
組合模式處理樹形結構的遍歷
觀察者模式當對象狀態變化時通知其他對象
迭代器模式提供統一的遍歷接口

八、最終小結

迭代器模式是一種非常實用的設計模式,特別適用于那些需要對不同類型的數據集合進行遍歷操作的場景。通過應用迭代器模式,我們不僅能夠簡化集合的遍歷邏輯,還能有效地將集合的具體實現細節與遍歷算法分離,從而提高代碼的靈活性和可維護性。


📌 一句話總結:

迭代器模式就像一個通用的遙控器,無論你的電視節目單(集合)如何組織,都能按順序播放每一個節目(元素)。


? 推薦使用方式:

  • 在需要對多種類型的集合進行遍歷時;
  • 希望保持集合類的封裝性,不讓外部直接訪問其內部結構時;
  • 支持多種遍歷策略時。

部分內容由AI大模型生成,注意識別!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/90347.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/90347.shtml
英文地址,請注明出處:http://en.pswp.cn/web/90347.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

docker安裝 Elasticsearch、Kibana、IK 分詞器

Elasticsearch 1.拉去鏡像 docker pull elasticsearch:8.12.2 docker pull kibana&#xff1a;8.12.22.創建掛載目錄 mkdir /root/elasticsearch3.不掛載啟動 docker run -d \ --restartalways \ --name fusion_elasticsearch \ --network fusion_network \ -p 9200:9200 \ -p …

Java面試寶典:Spring專題二

一、介紹下Spring中的事務 1.Spring事務的本質與價值 Spring事務本質是基于AOP的聲明式事務封裝,通過代理機制在目標方法前后注入事務管理邏輯(開啟、提交/回滾)。其核心價值在于: 業務解耦:將事務控制從業務代碼剝離,通過配置或注解管理(如@Transactional)。 統一抽…

DGMR壓縮技術:讓大規模視覺Transformer模型體積減半而性能不減

Transformer架構展現出卓越的擴展特性&#xff0c;其性能隨模型容量增長而持續提升。大規模模型在獲得優異性能的同時&#xff0c;也帶來了顯著的計算和存儲開銷。深入分析主流Transformer架構發現&#xff0c;多層感知器&#xff08;MLP&#xff09;模塊占據了模型參數的主要部…

JavaWeb學習打卡14(JSP內置對象及作用域)

JSP 中9 大內置對象PageContext // 用來存東西Request // 用來存東西ResponseSession // 用來存東西Application &#xff08;ServletContext&#xff09; // 用來存東西config &#xff08;ServletConfig&#xff09;outpage…

濤思數據參與起草中國工業互聯網研究院《工業數據庫規范》全系列標準

最近&#xff0c;《工業數據庫規范》系列團體標準正式發布。該標準由中國工業互聯網研究院牽頭&#xff0c;中國移動通信聯合會發布&#xff0c;共分為三部分—— 第1部分&#xff1a;云數據庫第2部分&#xff1a;實時數據庫第3部分&#xff1a;時序數據庫 濤思數據作為三項標…

使用exceljs導出luckysheet表格 純前端 支持離線使用

一.技術 exceljs&#xff0c;luckysheet 二.實現 參考網上博文exceljs對導出lucksheet表格的實現,發現存在一些問題并給予修復: 1.字體顏色、字號&#xff0c;加粗等適配的問題. 2.單元格對齊方式不生效; 3.單元格邊框無法繪制; 4.單元格邊框顏色及線型錯亂; 5.單元格列…

從0到1學習c++ 命名空間

也是好久沒寫博客了&#xff0c;主播這半年一直在忙別的領域&#xff0c;在磁力驅動領域干了一年&#xff0c;最好發現自己對這個領域并不是很感興趣&#xff0c;做這個領域多半都是為了發文章&#xff0c;現在閑下來了&#xff0c;主播終于也是過上好日子了&#xff0c;主播又…

大模型提示詞漏洞攻防測試:技術分析與實踐指南

引言 隨著ChatGPT、Claude、Gemini等大型語言模型(LLMs)的廣泛應用&#xff0c;它們已經成為現代AI系統的核心組件&#xff0c;被整合到各種產品和服務中。這些模型通過提示。Prompts)與用戶進行交互&#xff0c;而提示詞作為人類與AI溝通的橋梁&#xff0c;其安全性變得尤為重…

Golang實現 - 實現只有表頭的 Excel 模板,并在指定列添加了下拉框功能。生成的 Excel 文件在打開時,指定列的單元格會顯示下拉選項

該版本完全兼容最新版 excelize 庫 (v2.7)&#xff0c;實現了只有表頭的 Excel 模板&#xff0c;并在指定列添加了下拉框功能。生成的 Excel 文件在打開時&#xff0c;指定列的單元格會顯示下拉選擇箭頭。代碼如下&#xff1a;package mainimport ("fmt""log&qu…

全連接隊列

監聽套接字使用socket接口創建一個套接字&#xff0c;然后bind給套接字綁定地址&#xff0c;最后listen將套接字設置為監聽套接字。監聽套接字以前理解是三元組標識&#xff0c;后面看了netstat&#xff0c;覺得應該是五元組&#xff0c;只不過它這個五元組是{協議&#xff0c;…

JavaWeb-JSP

JSP JSP就是模板引擎 Template&#xff0c;因為看到的jsp是模板不變的&#xff0c;如果想讓頁面發生改變&#xff0c;就是自己添加java代碼改變頁面。有Java代碼&#xff0c;Tomcat服務器就會對jsp模板進行解析&#xff0c;解析完之后就是Servlet&#xff08;java類&#xff09…

大模型中常說的Token到底是什么?和Cookie和Session有什么區別?一文講清

什么是Token&#xff08;令牌&#xff09;Acesss Token是訪問資源接口&#xff08;API&#xff09;時所需要的資源憑證。簡單token的組成&#xff1a;uid(用戶唯一的身份標識)、time(當前時間的時間戳)、sign&#xff08;簽名&#xff0c;token的前幾位以哈希算法壓縮成的一定長…

RAGFlow:檢索增強生成技術的高效實現與深度探索

在當今信息爆炸的時代&#xff0c;如何從海量的數據中快速、準確地獲取并利用有價值的信息&#xff0c;成為了眾多領域面臨的關鍵挑戰。檢索增強生成&#xff08;Retrieval-Augmented Generation, RAG&#xff09;技術應運而生&#xff0c;它將信息檢索與大型語言模型&#xff…

【軌物洞見】光伏逆變器數據:分布式電站價值回歸的“第一塊多米諾骨牌”

1. 逆變器&#xff1a;光伏電站的核心“數據心臟” 逆變器是將光伏組件產生的直流電轉換為交流電的關鍵設備&#xff0c;其性能直接影響著整個電站的效率與穩定性。對其電壓、電流、功率參數以及故障告警信息進行遠程數據采集&#xff0c;是實現精細化運維和預測性維護的起點。…

如何在 npm 上發布 Element Plus 二次封裝組件

在一次開發中&#xff0c;小李接到一個重要的任務&#xff1a;將 Element Plus 中的時間組件根據團隊的獨特需求進行二次封裝。他靈機一動&#xff0c;決定將這個自定義組件打包成一個 npm 包&#xff0c;以便團隊的其他小伙伴們可以快速、方便地使用。接下來&#xff0c;讓我們…

vue2使用v-viewer圖片預覽:打開頁面自動預覽,禁止關閉預覽,解決在微信瀏覽器的頁面點擊事件老是觸發預覽初始化的問題

1、安裝&#xff1a; npm install v-viewer viewerjs2、在 main.js 中全局注冊&#xff1a; import Viewer from v-viewer; import viewerjs/dist/viewer.css; Vue.use(Viewer ); //配置項&#xff08;可選&#xff0c;根據需求調整&#xff09; // Vue.use(Viewer, { // d…

開源 Arkts 鴻蒙應用 開發(八)多媒體--相冊和相機

文章的目的為了記錄使用Arkts 進行Harmony app 開發學習的經歷。本職為嵌入式軟件開發&#xff0c;公司安排開發app&#xff0c;臨時學習&#xff0c;完成app的開發。開發流程和要點有些記憶模糊&#xff0c;趕緊記錄&#xff0c;防止忘記。 相關鏈接&#xff1a; 開源 Arkts …

無線通信資源分配相關算法

1.Maximum Clique First (MCF)是一種啟發式圖著色算法&#xff08;heuristic graph coloring algorithm&#xff09;&#xff0c;它的核心思想是&#xff1a;優先為圖中最大團&#xff08;maximum clique&#xff09;中的頂點分配不同的顏色&#xff0c;然后再依次為其他頂點上…

Kafka監控體系搭建:基于Prometheus+JMX+Grafana的全方位性能觀測方案

為什么需要Kafka監控監控架構概述步驟一&#xff1a;部署JMX Exporter 1.1 下載JMX Agent1.2 創建指標暴露配置 步驟二&#xff1a;配置Kafka集成JMX 2.1 啟動參數配置2.2 驗證指標暴露 步驟三&#xff1a;配置Prometheus采集 3.1 修改Prometheus配置3.2 驗證數據采集 步驟四&a…

stack 和 queue

目錄 一、stack 1.1 stack 的介紹 1.2 stack的使用 1&#xff09;最小棧 2&#xff09;棧的彈出壓入序列 3&#xff09;逆波蘭表達式求值 1.3 stack 的模擬使用 二、queue 2.1 queue的介紹 2.2 queue的使用 2.3 queue的模擬使用 三、容器適配器 3.1 什么是容器適配…