工廠模式案例與理解
阿新 • • 發佈:2018-11-25
工廠模式適用的場景:
1.使用者需要一個類的子類的例項,但不希望該類與子類形成耦合。
2.使用者需要一個類的子類的例項,單使用者不知道該類有哪些子類可用。
設計的核心思想是把類的例項化延遲到子類。
案例1 :java.util中的Iterator類的設計。
java中Collection介面繼承了Iterable介面,Iterable介面中定義了iterator()方法,所有實現了Collection介面的類都可以繼承該方法。
我們來看一下程式碼中具體是如何設計的。
我們一般這樣來獲得Iterator:
1 List<String> testArrayList = newArrayList<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類就能獲得例項。