• 工厂模式案例与理解


    工厂模式适用的场景:

    1.用户需要一个类的子类的实例,但不希望该类与子类形成耦合。

    2.用户需要一个类的子类的实例,单用户不知道该类有哪些子类可用。

    设计的核心思想是把类的实例化延迟到子类

    案例1 :java.util中的Iterator类的设计。

    java中Collection接口继承了Iterable接口,Iterable接口中定义了iterator()方法,所有实现了Collection接口的类都可以继承该方法。

    我们来看一下代码中具体是如何设计的。

    我们一般这样来获得Iterator:

    1 List<String> testArrayList = new ArrayList<String>();
    2 Iterator arrayListIterator = testArrayList.iterator();
    ArrayList类实现了Iterator()方法:
     1 /**
     2      * Returns an iterator over the elements in this list in proper sequence.
     3      *
     4      * <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
     5      *
     6      * @return an iterator over the elements in this list in proper sequence
     7      */
     8     public Iterator<E> iterator() {
     9         return new Itr();
    10     }
    11 
    12     /**
    13      * An optimized version of AbstractList.Itr
    14      */
    15     private class Itr implements Iterator<E> {
    16         int cursor;       // index of next element to return
    17         int lastRet = -1; // index of last element returned; -1 if no such
    18         int expectedModCount = modCount;
    19 
    20         public boolean hasNext() {
    21             return cursor != size;
    22         }
    23 
    24         @SuppressWarnings("unchecked")
    25         public E next() {
    26             checkForComodification();
    27             int i = cursor;
    28             if (i >= size)
    29                 throw new NoSuchElementException();
    30             Object[] elementData = ArrayList.this.elementData;
    31             if (i >= elementData.length)
    32                 throw new ConcurrentModificationException();
    33             cursor = i + 1;
    34             return (E) elementData[lastRet = i];
    35         }
    36 
    37         public void remove() {
    38             if (lastRet < 0)
    39                 throw new IllegalStateException();
    40             checkForComodification();
    41 
    42             try {
    43                 ArrayList.this.remove(lastRet);
    44                 cursor = lastRet;
    45                 lastRet = -1;
    46                 expectedModCount = modCount;
    47             } catch (IndexOutOfBoundsException ex) {
    48                 throw new ConcurrentModificationException();
    49             }
    50         }
    ArrayList的iterator返回一个实现了Iterator接口的内部类,该内部类实现了具体的ArrayList的Iterator的方法细节。

    再看下LinkedList是如何实现Iterator的:
      1 /**
      2      * Returns an iterator over the elements in this list (in proper
      3      * sequence).<p>
      4      *
      5      * This implementation merely returns a list iterator over the list.
      6      *
      7      * @return an iterator over the elements in this list (in proper sequence)
      8      */
      9     public Iterator<E> iterator() {
     10         return listIterator();
     11     }
     12 
     13 /**
     14      * {@inheritDoc}
     15      *
     16      * <p>This implementation returns {@code listIterator(0)}.
     17      *
     18      * @see #listIterator(int)
     19      */
     20     public ListIterator<E> listIterator() {
     21         return listIterator(0);
     22     }
     23 
     24 /**
     25      * {@inheritDoc}
     26      *
     27      * <p>This implementation returns a straightforward implementation of the
     28      * {@code ListIterator} interface that extends the implementation of the
     29      * {@code Iterator} interface returned by the {@code iterator()} method.
     30      * The {@code ListIterator} implementation relies on the backing list's
     31      * {@code get(int)}, {@code set(int, E)}, {@code add(int, E)}
     32      * and {@code remove(int)} methods.
     33      *
     34      * <p>Note that the list iterator returned by this implementation will
     35      * throw an {@link UnsupportedOperationException} in response to its
     36      * {@code remove}, {@code set} and {@code add} methods unless the
     37      * list's {@code remove(int)}, {@code set(int, E)}, and
     38      * {@code add(int, E)} methods are overridden.
     39      *
     40      * <p>This implementation can be made to throw runtime exceptions in the
     41      * face of concurrent modification, as described in the specification for
     42      * the (protected) {@link #modCount} field.
     43      *
     44      * @throws IndexOutOfBoundsException {@inheritDoc}
     45      */
     46     public ListIterator<E> listIterator(final int index) {
     47         rangeCheckForAdd(index);
     48 
     49         return new ListItr(index);
     50     }
     51 
     52 private class ListItr extends Itr implements ListIterator<E> {
     53         ListItr(int index) {
     54             cursor = index;
     55         }
     56 
     57         public boolean hasPrevious() {
     58             return cursor != 0;
     59         }
     60 
     61         public E previous() {
     62             checkForComodification();
     63             try {
     64                 int i = cursor - 1;
     65                 E previous = get(i);
     66                 lastRet = cursor = i;
     67                 return previous;
     68             } catch (IndexOutOfBoundsException e) {
     69                 checkForComodification();
     70                 throw new NoSuchElementException();
     71             }
     72         }
     73 
     74         public int nextIndex() {
     75             return cursor;
     76         }
     77 
     78         public int previousIndex() {
     79             return cursor-1;
     80         }
     81 
     82         public void set(E e) {
     83             if (lastRet < 0)
     84                 throw new IllegalStateException();
     85             checkForComodification();
     86 
     87             try {
     88                 AbstractList.this.set(lastRet, e);
     89                 expectedModCount = modCount;
     90             } catch (IndexOutOfBoundsException ex) {
     91                 throw new ConcurrentModificationException();
     92             }
     93         }
     94 
     95         public void add(E e) {
     96             checkForComodification();
     97 
     98             try {
     99                 int i = cursor;
    100                 AbstractList.this.add(i, e);
    101                 lastRet = -1;
    102                 cursor = i + 1;
    103                 expectedModCount = modCount;
    104             } catch (IndexOutOfBoundsException ex) {
    105                 throw new ConcurrentModificationException();
    106             }
    107         }
    108     }
    由于ArrayList和LinkedList的底层实现一个使用动态数组、一个使用链表,所以Iterator的实现细节必然不同。
    但是这种不同并没有反映在我们的使当中,对于这两种不同我们并没有实用类似
    //以下代码是我瞎编的,并不存在这两个类
    ArrayLiArrayListIterator arrayListIterator  = new ArrayLiArrayListIterator ();
    LinkedListIterator linkedListIterator = new LinkedListIterator();

    的方法获得实例,而是直接用List类就能获得实例。



  • 相关阅读:
    VUE学习一,安装及Hello World
    609. 在系统中查找重复文件
    451. 根据字符出现频率排序
    面试题 10.02. 变位词组
    142. 环形链表 II
    面试题 16.24. 数对和
    151. 翻转字符串里的单词
    1207. 独一无二的出现次数
    80. 删除排序数组中的重复项 II
    1365. 有多少小于当前数字的数字
  • 原文地址:https://www.cnblogs.com/cxy2016/p/10014980.html
Copyright © 2020-2023  润新知