Head First 設計模式之迭代器與組合模式(Java例子)

前言:

來源於《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,如果方法無意義,則無需修改默認繼承就可以了

總結:

其實就是相當於樹,每個節點可能是單個物體、也可能是一個集合。藉此來進行分類,構建一個巨大的分類菜單

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章