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,如果方法无意义,则无需修改默认继承就可以了

总结:

其实就是相当于树,每个节点可能是单个物体、也可能是一个集合。借此来进行分类,构建一个巨大的分类菜单

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