工厂模式案例与理解
工厂模式适用的场景:
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类就能获得实例。