美文网首页
设计模式:工厂方法

设计模式:工厂方法

作者: 谁家的猪 | 来源:发表于2019-07-16 08:08 被阅读0次

    定义与类型

    定义:定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行。
    类型:创建型

    适用场景

    • 创建对象需要大量重复代码
    • 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节
    • 一个类通过其子类来制定创建哪个对象

    优点

    • 用户只需要关心所需产品对应的工厂,无须关心创建细节
    • 加入新产品符合开闭原则,提高可扩展性

    缺点

    • 类的个数容易过多,增加复杂度
    • 增加了系统的抽象性和理解难度

    代码示例

    以之前的简单工厂,不同的课程视频为例

    1. 创建VideoFactory类
    /**
     * @author lijiayin
     */
    public abstract class VideoFactory {
        public abstract Video getVideo();
    }
    
    1. 创建Video类
    /**
     * @author lijiayin
     */
    public abstract class Video {
        
        public abstract void produce();
    }
    
    1. 创建JavaVideo类
    /**
     * @author lijiayin
     */
    public class JavaVideo extends Video {
        @Override
        public void produce() {
            System.out.println("Java");
        }
    }
    
    1. 创建PythonVideo类
    /**
     * @author lijiayin
     */
    public class PythonVideo extends Video {
        @Override
        public void produce() {
            System.out.println("Python");
        }
    }
    
    
    1. 创建JavaVideoFactory类
    /**
     * @author lijiayin
     */
    public class JavaVideoFactory extends VideoFactory {
        @Override
        public Video getVideo() {
            return new JavaVideo();
        }
    }
    
    1. 创建PythonVideoFactory类
    /**
     * @author lijiayin
     */
    public class PythonVideoFactory extends VideoFactory {
        @Override
        public Video getVideo() {
            return new PythonVideo();
        }
    }
    
    1. 创建测试类
    /**
     * @author lijiayin
     */
    public class Test {
        public static void main(String[] args) {
            VideoFactory videoFactory = new JavaVideoFactory();
            Video video = videoFactory.getVideo();
            video.produce();
            VideoFactory videoFactory2 = new PythonVideoFactory();
            Video video2 = videoFactory2.getVideo();
            video2.produce();
        }
    }
    
    1. 测试结果


      测试结果.png
    2. UML图


      UML.png

    JDK示例

    • Collection接口,相当于VideoFactory抽象类,定义了Iterator<E> iterator()方法,相当于Video getVideo()方法;
    public interface Collection<E> extends Iterable<E> {
        ......
        Iterator<E> iterator();
        ......
    }
    
    • ArrayList类,相当于JavaVideoFactory类,实现了具体的iterator()方法;
    public class ArrayList<E> extends AbstractList<E>
            implements List<E>, RandomAccess, Cloneable, java.io.Serializable
    {
        ......
        public Iterator<E> iterator() {
            return new Itr();
        }
        ......
    }
    
    • Iterator接口,相当于Video抽象类,定义了需要实现的产品;
    package java.util;
    
    import java.util.function.Consumer;
    
    /**
     * An iterator over a collection.  {@code Iterator} takes the place of
     * {@link Enumeration} in the Java Collections Framework.  Iterators
     * differ from enumerations in two ways:
     *
     * <ul>
     *      <li> Iterators allow the caller to remove elements from the
     *           underlying collection during the iteration with well-defined
     *           semantics.
     *      <li> Method names have been improved.
     * </ul>
     *
     * <p>This interface is a member of the
     * <a href="{@docRoot}/../technotes/guides/collections/index.html">
     * Java Collections Framework</a>.
     *
     * @param <E> the type of elements returned by this iterator
     *
     * @author  Josh Bloch
     * @see Collection
     * @see ListIterator
     * @see Iterable
     * @since 1.2
     */
    public interface Iterator<E> {
        /**
         * Returns {@code true} if the iteration has more elements.
         * (In other words, returns {@code true} if {@link #next} would
         * return an element rather than throwing an exception.)
         *
         * @return {@code true} if the iteration has more elements
         */
        boolean hasNext();
    
        /**
         * Returns the next element in the iteration.
         *
         * @return the next element in the iteration
         * @throws NoSuchElementException if the iteration has no more elements
         */
        E next();
    
        /**
         * Removes from the underlying collection the last element returned
         * by this iterator (optional operation).  This method can be called
         * only once per call to {@link #next}.  The behavior of an iterator
         * is unspecified if the underlying collection is modified while the
         * iteration is in progress in any way other than by calling this
         * method.
         *
         * @implSpec
         * The default implementation throws an instance of
         * {@link UnsupportedOperationException} and performs no other action.
         *
         * @throws UnsupportedOperationException if the {@code remove}
         *         operation is not supported by this iterator
         *
         * @throws IllegalStateException if the {@code next} method has not
         *         yet been called, or the {@code remove} method has already
         *         been called after the last call to the {@code next}
         *         method
         */
        default void remove() {
            throw new UnsupportedOperationException("remove");
        }
    
        /**
         * Performs the given action for each remaining element until all elements
         * have been processed or the action throws an exception.  Actions are
         * performed in the order of iteration, if that order is specified.
         * Exceptions thrown by the action are relayed to the caller.
         *
         * @implSpec
         * <p>The default implementation behaves as if:
         * <pre>{@code
         *     while (hasNext())
         *         action.accept(next());
         * }</pre>
         *
         * @param action The action to be performed for each element
         * @throws NullPointerException if the specified action is null
         * @since 1.8
         */
        default void forEachRemaining(Consumer<? super E> action) {
            Objects.requireNonNull(action);
            while (hasNext())
                action.accept(next());
        }
    }
    
    
    • ArrayList的内部类Itr,相当于JavaVideo类,具体实现了产品;
    public class ArrayList<E> extends AbstractList<E>
            implements List<E>, RandomAccess, Cloneable, java.io.Serializable
    {
        ......
        /**
         * An optimized version of AbstractList.Itr
         */
        private class Itr implements Iterator<E> {
            int cursor;       // index of next element to return
            int lastRet = -1; // index of last element returned; -1 if no such
            int expectedModCount = modCount;
    
            Itr() {}
    
            public boolean hasNext() {
                return cursor != size;
            }
    
            @SuppressWarnings("unchecked")
            public E next() {
                checkForComodification();
                int i = cursor;
                if (i >= size)
                    throw new NoSuchElementException();
                Object[] elementData = ArrayList.this.elementData;
                if (i >= elementData.length)
                    throw new ConcurrentModificationException();
                cursor = i + 1;
                return (E) elementData[lastRet = i];
            }
    
            public void remove() {
                if (lastRet < 0)
                    throw new IllegalStateException();
                checkForComodification();
    
                try {
                    ArrayList.this.remove(lastRet);
                    cursor = lastRet;
                    lastRet = -1;
                    expectedModCount = modCount;
                } catch (IndexOutOfBoundsException ex) {
                    throw new ConcurrentModificationException();
                }
            }
    
            @Override
            @SuppressWarnings("unchecked")
            public void forEachRemaining(Consumer<? super E> consumer) {
                Objects.requireNonNull(consumer);
                final int size = ArrayList.this.size;
                int i = cursor;
                if (i >= size) {
                    return;
                }
                final Object[] elementData = ArrayList.this.elementData;
                if (i >= elementData.length) {
                    throw new ConcurrentModificationException();
                }
                while (i != size && modCount == expectedModCount) {
                    consumer.accept((E) elementData[i++]);
                }
                // update once at end of iteration to reduce heap write traffic
                cursor = i;
                lastRet = i - 1;
                checkForComodification();
            }
    
            final void checkForComodification() {
                if (modCount != expectedModCount)
                    throw new ConcurrentModificationException();
            }
        }
        ......
    }
    

    相关文章

      网友评论

          本文标题:设计模式:工厂方法

          本文链接:https://www.haomeiwen.com/subject/fuubkctx.html