Iterator 使用場景
A. 切割出遍歷物件,對於 不同物件可有不同遍歷方法
B. 一個物件的遍歷如果透過內部自己提供,會使的該物件承擔過多責任 (也不易維護),但是如果提供給使用者就暴露了內部細節,這時就可以使用 跌代模式
C. 提供一個方法取得容器物件的每個元素,又不對外暴露
Iterator 定義 & Iterator UML
● Iterator 的定義
提供一種方法(界面),用來訪問一個容器中的所有元素,而不對外暴露細節
● Iterator 角色介紹
角色 | 說明 |
---|---|
Aggregate (容器接口) | 提供一個類創建 Iterator 的方法 |
ConcreteAggreate | 實現容器的內容,內部有一個存放數據的容器 |
Iterator (迭代接口) | 負責訪問、遍歷容器的核心方法 |
ConcreteIterator | 實際去遍歷容器中的數據,內部會有一個 cursor 去紀錄使用者的操作行為 |
● 圖中 Aggregate 的方法對應 Java#
Iterator
的方法如下表
Aggregate#Method Java Iterator#Method First() - IsDone() hasNext() Next() next() CurrentItem() - - remove()
Iterator 設計:優缺點
● Iterator 設計優點:隔離出物件儲存、物件遍歷兩項行為
A. 單一職責:一個類負責一個責任;Iterator 類就是負責遍歷容器內的元素
B. 界面隔離:最小化界面,不讓容器負擔遍歷的責任
● Iterator 設計缺點:
A. 非必要性:其最大的缺點其實就是大多數語言都對各自的容器內實現了 Iterator 的功能,我們幾乎很少有需要自己實現(當然除非一些特殊狀況或需求)
B. 複雜化:自己時現實的複雜化,因為類的增加使用者使用起來會稍加複雜
Iterator 實現
Iterator 標準
A. Iterator
界面:這裡我們自己配合泛型實現一個 Iterator,有迭代容器的核心方法
interface MyIterator<T> {
fun hasNext(): Boolean
fun next(): T
fun remove() : Boolean
}
B. CreteIterator
類:實做遍歷的方法;在這裡面有 cursor 紀錄使用者對於遍歷的操作
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
}
}
C. Aggregate
界面:提供使用者操控該容器的方法(add
, remove
...),但不提供直接遍歷容器的方法,改成提供 MyIterator 類
interface MyAggregate<T> {
fun add(item: T)
fun remove(item: T)
// 關聯 MyIterator
fun createIterator() : MyIterator<T>
}
D. ConcreteAggregate
類:它是一個容器類,保存數據並提供使用者操作數據的方法,但並不包括提供直接遍歷數據的方法(實做 MyIterator)
這個類負責串起 Iterator 的關係
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())
}
}
● 為何要使用
list.toMutableList()
?這是一種 快照 作法,
toMutableList()
會複製原本陣列的物件,而不是取得引用,這樣在使用上更安全,因為 Iterator 是取用副本的操作public fun <T> Collection<T>.toMutableList(): MutableList<T> { return ArrayList(this) }
E. 使用方式:以往是直接透過容器遍歷,現在改用取得 MyIterator 來遍歷
●
createIterator
方法是返回一個遍歷的對象,而不是容器內部持有對象,所以請不要在遍歷的過程中使用// 以下使用嚴重錯誤! while (createIterator().hasNext()) { println("item: ${createIterator().next()}") }
fun main() {
ConcreteAggregator().apply {
add("Hello")
add("World")
add("Iterator")
add("Design")
}.run {
val iterator = createIterator()
while(iterator.hasNext()) {
println("item: ${iterator.next()}")
}
}
}
Java
Iterator & Iterable 差異
接口 | 說明 / 功能 |
---|---|
Iterable | 從這個界面繼承的類可以表示為可以迭代的元素序列 |
Iterator | 可以表示為元素序列的集合或另一個實體的迭代器;允許順序訪問元 |
更多的物件導向設計
物件導向的設計基礎如下,如果是初學者或是不熟悉的各位,建議可以從這些基礎開始認識,打好基底才能走個更穩(在學習的時候也需要不斷回頭看)!
創建模式 Creation Patterns
● 創建模式 PK
● 創建模式 - Creation Patterns
:
創建模式用於「物件的創建」,它關注於如何更靈活、更有效地創建物件。這些模式可以隱藏創建物件的細節,並提供創建物件的機制,例如單例模式、工廠模式… 等等,詳細解說請點擊以下連結
● Singleton 單例模式 | 解說實現 | Android Framework Context Service
● Abstract Factory 設計模式 | 實現解說 | Android MediaPlayer
● Factory 工廠方法模式 | 解說實現 | Java 集合設計
● Builder 建構者模式 | 實現與解說 | Android Framwrok Dialog 視窗
● Clone 原型模式 | 解說實現 | Android Framework Intent
● Object Pool 設計模式 | 實現與解說 | 利用 JVM
● Flyweight 享元模式 | 實現與解說 | 物件導向設計
● Observer 觀察者模式 | JDK Observer | Android Framework Listview
行為模式 Behavioral Patterns
● 行為模式 PK
● 行為模式 - Behavioral Patterns
:
行為模式關注物件之間的「通信」和「職責分配」。它們描述了一系列物件如何協作,以完成特定任務。這些模式專注於改進物件之間的通信,從而提高系統的靈活性。例如,策略模式、觀察者模式… 等等,詳細解說請點擊以下連結
● Stragety 策略模式 | 解說實現 | Android Framework 動畫
● Interpreter 解譯器模式 | 解說實現 | Android Framework PackageManagerService
● Chain 責任鏈模式 | 解說實現 | Android Framework View 事件傳遞
● Specification 規格模式 | 解說實現 | Query 語句實做
● Command 命令、Servant 雇工模式 | 實現與解說 | 物件導向設計
● Memo 備忘錄模式 | 實現與解說 | Android Framwrok Activity 保存
● Visitor 設計模式 | 實現與解說 | 物件導向設計
● Template 設計模式 | 實現與解說 | 物件導向設計
結構模式 Structural Patterns
● 結構模式 PK
● 結構模式 - Structural Patterns
:
結構模式專注於「物件之間的組成」,以形成更大的結構。這些模式可以幫助你確保當系統進行擴展或修改時,不會破壞其整體結構。例如,外觀模式、代理模式… 等等,詳細解說請點擊以下連結
● Decorate 裝飾模式 | 解說實現 | 物件導向設計
● Iterator 迭代設計 | 解說實現 | 物件導向設計