前言:
來源於《head first 設計模式》。當作讀書筆記了,這次看的是第9章模版方法模式。最後剩下沒幾章了,這幾天花時間看完了,現在來纔來寫下記錄。
迭代器模式的概念
提供一種方法順序訪問一個聚合對象中的各個元素,而又不暴露其內部的表示
適配器模式的uml圖
角色介紹:
- Clinet:代表客戶代碼
- Aggregate:一個共同的接口供所有的聚合使用,將客戶代碼與具體的集合對象實現解耦。
- ConcreteAggregate:一個具體的聚合持用一個對象的集合,並實現一個方法,利用此方法返回該集合的迭代器。
- Iterator:這是所有迭代器都必須實現的接口,它包含一些迭代器所需方法,用於操作集合
- ConcreteIterator:這個具體的迭代器負責管理目前遍歷的位置。
例子
光說無用,這裏用java源碼來解釋。
Collection,所有集合的頂部接口-----ConcreteAggregate
public interface Collection<E> extends Iterable<E> {
Iterator<E> iterator();
}
這裏只截取部分與迭代器相關的代碼。這裏的iterator()相當於createiterator()都是獲取一個迭代器。
Iterator------Iterator
public interface Iterator<E> {
boolean hasNext();
E next();
default void remove() {
throw new UnsupportedOperationException("remove");
}
這是所有迭代器的都必須實現的接口,包含了一些基本的操作集合的方法
HashIterator是hashMap中的內部類-------ConcreteIterator
abstract class HashIterator {
Node<K,V> next; // next entry to return
Node<K,V> current; // current entry
int expectedModCount; // for fast-fail
int index; // current slot
HashIterator() {
expectedModCount = modCount;
Node<K,V>[] t = table;
current = next = null;
index = 0;
if (t != null && size > 0) { // advance to first entry
do {} while (index < t.length && (next = t[index++]) == null);
}
}
public final boolean hasNext() {
return next != null;
}
final Node<K,V> nextNode() {
Node<K,V>[] t;
Node<K,V> e = next;
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
if (e == null)
throw new NoSuchElementException();
if ((next = (current = e).next) == null && (t = table) != null) {
do {} while (index < t.length && (next = t[index++]) == null);
}
return e;
}
public final void remove() {
Node<K,V> p = current;
if (p == null)
throw new IllegalStateException();
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
current = null;
K key = p.key;
removeNode(hash(key), key, null, false, false);
expectedModCount = modCount;
}
}
final class KeyIterator extends HashIterator
implements Iterator<K> {
public final K next() { return nextNode().key; }
}
final class ValueIterator extends HashIterator
implements Iterator<V> {
public final V next() { return nextNode().value; }
}
final class EntryIterator extends HashIterator
implements Iterator<Map.Entry<K,V>> {
public final Map.Entry<K,V> next() { return nextNode(); }
}
HashIterator實現了所有的iterator的基本方法,而其只是抽象類,正在實現Iterator的是繼承了HashIterator的EntryIterator、ValueIterator、KeyIterator。其實這裏只是把重複代碼抽象出來到HashIterator,基本實現是於uml無區別的。都是實現迭代器接口的方法。
EntrySet-----ConcreteAggregate
final class EntrySet extends AbstractSet<Map.Entry<K,V>> {
public final Iterator<Map.Entry<K,V>> iterator() {
return new EntryIterator();
}
}
唏噓,選錯了集合選了個hashmap,hashMap的迭代器是針對key的或者針對entry的,所以有點亂哈哈哈哈哈,這裏就是他內部的EntrySet追根到底他還是實現了collection,實現了方法返回key value的迭代器。我們一般調用就是獲取的話是用,map.entrySet.Iterator獲取key value的迭代器。差不多哈。
總結:
其實就是每個集合都不會有它不一樣的遍歷方法,我們採用迭代器的模式來對遍歷過程進行封裝,而我們不需要知道內部是如何訪問的,即不再知道我們是用什麼集合來存儲數據的,只需得到其迭代器即可操作集合。
組合模式
組合模式的概念
組合模式允許將對象組合成屬性結構來表現“整體/部分”層次結構,組合能讓客戶以一致的方式處理個別對象以及對象組合。
組合模式uml圖
這是網上找到一張圖,偷了點懶。
特點:
樹形結構表示對象組合
忽略對象組合和對象個體之間的差別,即相同的操作既可以作用於對象組合,也可以作用與對象個體
注意:
因爲繼承方法中,有些方法只有對葉子節點有意義,而有些方法只對非葉子節點有意義,我們可以將基類的方法默認實現爲拋出UnsupportedOperationException,如果方法無意義,則無需修改默認繼承就可以了
總結:
其實就是相當於樹,每個節點可能是單個物體、也可能是一個集合。藉此來進行分類,構建一個巨大的分類菜單