工厂模式案例与理解

工厂模式适用的场景:

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类就能获得实例。



猜你喜欢

转载自www.cnblogs.com/cxy2016/p/10014980.html