--- title: 'Iterator 迭代器模式' disqus: kyleAlien --- Iterator 迭代器模式 === ## Overview of Content :::success * 如果喜歡讀更好看一點的網頁版本,可以到我新做的網站 [**DevTech Ascendancy Hub**](https://devtechascendancy.com/) 本篇文章對應的是 [**Iterator 迭代設計 | 解說實現 | 物件導向設計**](https://devtechascendancy.com/object-oriented_design_iterator/) ::: [TOC] ## Iterator 使用場景 1. 切割出遍歷物件,對於 **不同物件可有不同遍歷方法** 2. 一個物件的遍歷如果透過**內部自己提供,會使的該物件承擔過多責任** (也不易維護),但是如果**提供給使用者就暴露了內部細節**,這時就可以使用 **跌代模式** 3. 提供一個方法取得容器物件的每個元素,又不對外暴露 ### Iterator 定義 & Iterator UML * Iterator 的定義 提供一種方法(界面),用來訪問一個容器中的所有元素,而不對外暴露細節 * Iterator 角色介紹 | 角色 | 說明 | | - | - | | Aggregate (容器接口) | 提供一個類創建 Iterator 的方法 | | ConcreteAggreate | 實現容器的內容,**內部有一個存放數據的容器** | | Iterator (迭代接口) | 負責訪問、遍歷容器的核心方法 | | ConcreteIterator | 實際去遍歷容器中的數據,內部會有一個 cursor 去紀錄使用者的操作行為 | > ![](https://i.imgur.com/s7fj0sP.png) :::info * 圖中 Aggregate 的方法對應 Java#Iterator 的方法如下表 | Aggregate#Method | Java Iterator#Method | | - | - | | First() | - | | IsDone() | hasNext() | | Next() | next() | | CurrentItem() | - | | - | remove() | ::: ### Iterator 設計 - 優缺點 * **Iterator 設計優點**:隔離出物件儲存、物件遍歷兩項行為 1. **單一職責**:一個類負責一個責任;Iterator 類就是負責遍歷容器內的元素 2. **界面隔離**:最小化界面,不讓容器負擔遍歷的責任 * **Iterator 設計缺點**: 1. **非必要性**:其最大的缺點其實就是大多數語言都對各自的容器內實現了 Iterator 的功能,我們幾乎很少有需要自己實現(當然除非一些特殊狀況或需求) 2. **複雜化**:自己時現實的複雜化,因為類的增加使用者使用起來會稍加複雜 ## Iterator 實現 ### Iterator 標準 1. **`Iterator` 界面**:這裡我們自己配合泛型實現一個 Iterator,有迭代容器的核心方法 ```kotlin= interface MyIterator<T> { fun hasNext(): Boolean fun next(): T fun remove() : Boolean } ``` 2. **`CreteIterator` 類**:實做遍歷的方法;在這裡面有 cursor 紀錄使用者對於遍歷的操作 ```kotlin= class MyConcreteIterator<T> constructor(val list: MutableList<T>): MyIterator<T> { private var cursor: Int = 0 override fun hasNext(): Boolean { return cursor != list.size } override fun next(): T { // 移動指標 return list[cursor++] } override fun remove(): Boolean { // 移動指標 list.removeAt(cursor++) return true } } ``` 3. **`Aggregate` 界面**:提供使用者操控該容器的方法(`add`, `remove`...),**但不提供直接遍歷容器的方法,改成提供 MyIterator 類** ```kotlin= interface MyAggregate<T> { fun add(item: T) fun remove(item: T) // 關聯 MyIterator fun createIterator() : MyIterator<T> } ``` 4. **`ConcreteAggregate` 類**:它是一個容器類,保存數據並提供使用者操作數據的方法,但並不包括提供直接遍歷數據的方法(實做 MyIterator) > 這個類負責串起 Iterator 的關係 ```kotlin= class ConcreteAggregator: MyAggregate<String> { private val list = mutableListOf<String>() override fun add(item: String) { list.add(item) } override fun remove(item: String) { list.remove(item) } override fun createIterator(): MyIterator<String> { // 串起其關係 return MyConcreteIterator(list.toMutableList()) } } ``` :::success * 為何要使用 `list.toMutableList()` ? 這是一種 **快照** 作法,`toMutableList()` 會複製原本陣列的物件,而不是取得引用,這樣在使用上更安全,因為 Iterator 是取用副本的操作 ```kotlin= public fun <T> Collection<T>.toMutableList(): MutableList<T> { return ArrayList(this) } ``` ::: 5. **使用方式**:以往是直接透過容器遍歷,現在改用取得 MyIterator 來遍歷 :::warning * `createIterator` 方法是返回一個遍歷的對象,而不是容器內部持有對象,所以請不要在遍歷的過程中使用 ```kotlin= // 以下使用嚴重錯誤! while (createIterator().hasNext()) { println("item: ${createIterator().next()}") } ``` ::: ```kotlin= fun main() { ConcreteAggregator().apply { add("Hello") add("World") add("Iterator") add("Design") }.run { val iterator = createIterator() while(iterator.hasNext()) { println("item: ${iterator.next()}") } } } ``` > ![](https://i.imgur.com/QhnBWAx.png) ## Java ### Iterator & Iterable 差異 | 接口 | 說明 / 功能 | | - | - | | Iterable | 從這個界面繼承的類可以表示為可以迭代的元素序列 | | Iterator | 可以表示為元素序列的集合或另一個實體的迭代器;允許順序訪問元素 | > ![](https://i.imgur.com/SnwmbYn.png) ## 更多的物件導向設計 物件導向的設計基礎如下,如果是初學者或是不熟悉的各位,建議可以從這些基礎開始認識,打好基底才能走個更穩(在學習的時候也需要不斷回頭看)! :::info * [**設計建模 2 大概念- UML 分類、使用**](https://devtechascendancy.com/introduction-to-uml-and-diagrams/) * [**物件導向設計原則 – 6 大原則(一)**](https://devtechascendancy.com/object-oriented-design-principles_1/) * [**物件導向設計原則 – 6 大原則(二)**](https://devtechascendancy.com/object-oriented-design-principles_2/) ::: ### 創建模式 - Creation Patterns * [**創建模式 PK**](https://devtechascendancy.com/pk-design-patterns-factory-builder-best/) * **創建模式 - `Creation Patterns`**: 創建模式用於「**物件的創建**」,它關注於如何更靈活、更有效地創建對象。這些模式可以隱藏創建對象的細節,並提供創建對象的機制,例如單例模式、工廠模式… 等等,詳細解說請點擊以下連結 :::success * [**Singleton 單例模式 | 解說實現 | Android Framework Context Service**](https://devtechascendancy.com/object-oriented_design_singleton/) * [**Abstract Factory 設計模式 | 實現解說 | Android MediaPlayer**](https://devtechascendancy.com/object-oriented_design_abstract-factory/) * [**Factory 工廠方法模式 | 解說實現 | Java 集合設計**](https://devtechascendancy.com/object-oriented_design_factory_framework/) * [**Builder 建構者模式 | 實現與解說 | Android Framwrok Dialog 視窗**](https://devtechascendancy.com/object-oriented_design_builder_dialog/) * [**Clone 原型模式 | 解說實現 | Android Framework Intent**](https://devtechascendancy.com/object-oriented_design_clone_framework/) * [**Object Pool 設計模式 | 實現與解說 | 利用 JVM**](https://devtechascendancy.com/object-oriented_design_object-pool/) * [**Flyweight 享元模式 | 實現與解說 | 物件導向設計**](https://devtechascendancy.com/object-oriented_design_flyweight/) ::: ### 行為模式 - Behavioral Patterns * [**行為模式 PK**](https://devtechascendancy.com/pk-design-patterns-cmd-strat-state-obs-chain/) * **行為模式 - `Behavioral Patterns`**: 行為模式關注物件之間的「**通信**」和「**職責分配**」。它們描述了一系列對象如何協作,以完成特定任務。這些模式專注於改進物件之間的通信,從而提高系統的靈活性。例如,策略模式、觀察者模式… 等等,詳細解說請點擊以下連結 :::warning * [**Stragety 策略模式 | 解說實現 | Android Framework 動畫**](https://devtechascendancy.com/object-oriented_design_stragety_framework/) * [**Interpreter 解譯器模式 | 解說實現 | Android Framework PackageManagerService**](https://devtechascendancy.com/object-oriented_design_interpreter_framework/) * [**Chain 責任鏈模式 | 解說實現 | Android Framework View 事件傳遞**](https://devtechascendancy.com/object-oriented_design_chain_framework/) * [**State 狀態模式 | 實現解說 | 物件導向設計**](https://devtechascendancy.com/object-oriented_design_state/) * [**Specification 規格模式 | 解說實現 | Query 語句實做**](https://devtechascendancy.com/object-oriented_design_specification-query/) * [**Command 命令、Servant 雇工模式 | 實現與解說 | 物件導向設計**](https://devtechascendancy.com/object-oriented_design_command_servant/) * [**Memo 備忘錄模式 | 實現與解說 | Android Framwrok Activity 保存**](https://devtechascendancy.com/object-oriented_design_memo_framework/) * [**Visitor 設計模式 | 實現與解說 | 物件導向設計**](https://devtechascendancy.com/object-oriented_design_visitor_dispatch/) * [**Template 設計模式 | 實現與解說 | 物件導向設計**](https://devtechascendancy.com/object-oriented_design_template/) * [**Mediator 模式設計 | 實現與解說 | 物件導向設計**](https://devtechascendancy.com/object-oriented_programming_mediator/) * [**Composite 組合模式 | 實現與解說 | 物件導向設計**](https://devtechascendancy.com/object-oriented_programming_composite/) ::: ### 結構模式 - Structural Patterns * [**結構模式 PK**](https://devtechascendancy.com/pk-design-patterns-proxy-decorate-adapter/) * **結構模式 - `Structural Patterns`**: 結構模式專注於「物件之間的組成」,以形成更大的結構。這些模式可以幫助你確保當系統進行擴展或修改時,不會破壞其整體結構。例如,外觀模式、代理模式… 等等,詳細解說請點擊以下連結 :::danger * [**Bridge 橋接模式 | 解說實現 | 物件導向設計**](https://devtechascendancy.com/object-oriented_design_bridge/) * [**Decorate 裝飾模式 | 解說實現 | 物件導向設計**](https://devtechascendancy.com/object-oriented_design_decorate/) * [**Proxy 代理模式 | 解說實現 | 分析動態代理**](https://devtechascendancy.com/object-oriented_design_proxy_dynamic-proxy/) * [**Iterator 迭代設計 | 解說實現 | 物件導向設計**](https://devtechascendancy.com/object-oriented_design_iterator/) * [**Facade 外觀、門面模式 | 解說實現 | 物件導向設計**](https://devtechascendancy.com/object-oriented_design_facade/) * [**Adapter 設計模式 | 解說實現 | 物件導向設計**](https://devtechascendancy.com/object-oriented_design_adapter/) ::: ## Appendix & FAQ :::info ::: ###### tags: `Java 設計模式` `基礎進階`