テンプレートの方法

3097 ワード

  • 意図
  • 動作中のアルゴリズムの骨格を定義し、いくつかのステップをサブクラスに遅延させる.テンプレート方法は、サブクラスがアルゴリズムの構造を変えずに、アルゴリズムの特定のステップを再定義することができるようにする.
  • モチベーション
  • 一つのテンプレート方法はいくつかの抽象的な操作でアルゴリズムを定義し、サブクラスはこれらの動作を再定義して具体的な挙動を提供し、それぞれの需要を満たす.
  • 適用性
  • は、アルゴリズムの不変部分を一度に実現し、可変挙動をサブクラスに残して実現する.
  • 各サブクラスにおける共通の挙動は、コードの重複を回避するために、共通の親クラスに抽出されるべきである.
  • は、サブクラス拡張を制御し、テンプレート方法は、これらの点でのみ拡張を可能にする「hook」動作を特定のポイントで起動する.
  • 実際のテンプレート方法
  • jdkソースHashMapとLinkdhashMapは、高速なランダムアクセスアルゴリズムです.HashMapコンストラクタにおいてアルゴリズムの骨格を定義し,拡張点としてデフォルトのフックを定義し,サブクラスに実装した.
       /**
         * Constructs an empty HashMap with the specified initial
         * capacity and load factor.
         *
         * @param  initialCapacity the initial capacity
         * @param  loadFactor      the load factor
         * @throws IllegalArgumentException if the initial capacity is negative
         *         or the load factor is nonpositive
         */
        public HashMap(int initialCapacity, float loadFactor) {
            if (initialCapacity < 0)
                throw new IllegalArgumentException("Illegal initial capacity: " +
                                                   initialCapacity);
            if (initialCapacity > MAXIMUM_CAPACITY)
                initialCapacity = MAXIMUM_CAPACITY;
            if (loadFactor <= 0 || Float.isNaN(loadFactor))
                throw new IllegalArgumentException("Illegal load factor: " +
                                                   loadFactor);
    
            this.loadFactor = loadFactor;
            threshold = initialCapacity;
            init();  //  
        }
    
      /**
         * Initialization hook for subclasses. This method is called
         * in all constructors and pseudo-constructors (clone, readObject)
         * after HashMap has been initialized but before any entries have
         * been inserted.  (In the absence of this method, readObject would
         * require explicit knowledge of subclasses.)
         */
        void init() {
        }
    
    Linked HashMapは親の構造方法を呼び出し、同時にフックに実装を提供し、HashMapの順序にアクセスする能力を与えました.
    public class LinkedHashMap
        extends HashMap
        implements Map
    {
      /**
         * Constructs an empty insertion-ordered LinkedHashMap instance
         * with the specified initial capacity and load factor.
         *
         * @param  initialCapacity the initial capacity
         * @param  loadFactor      the load factor
         * @throws IllegalArgumentException if the initial capacity is negative
         *         or the load factor is nonpositive
         */
        public LinkedHashMap(int initialCapacity, float loadFactor) {
            super(initialCapacity, loadFactor);
            accessOrder = false;
        }
    
       /**
         * Called by superclass constructors and pseudoconstructors (clone,
         * readObject) before any entries are inserted into the map.  Initializes
         * the chain.
         */
        @Override
        void init() {
            header = new Entry<>(-1, null, null, null);
            header.before = header.after = header;
        }
    }
    
    このように記憶されている役割は親に委ねられ、自身は記憶順序の維持のみに注目する.例はjdk 1.7で、jdk 1.8はもうこのような方式を採用しませんでした.
  • を参照してください.
    設計モード――オブジェクト指向ソフトウェアの基礎を多重化することができる.