1. 程式人生 > >工廠模式案例與理解

工廠模式案例與理解

工廠模式適用的場景:

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類就能獲得例項。