工厂方法模式是定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行。属于创建型,也属于GOF23种设计模式。
适用范围
- 1.创建对象需要大量重复的代码。
- 2.客户端(应用层)不依赖于产品类实例如何被创建、实现等细节。
- 3.一个类通过其子类来指定创建哪个对象。
优缺点
优点:用户只需要关心所需产品对应的工厂,无需关心创建细节。加入新产品符合开闭原则,提高可扩展性。
缺点:类的个人容易过多,增加复杂度。增加了系统的抽象性和理解难度。
示例
Video.java
视频抽象类,提供生产视频的抽象方法。
1 2 3 4 5 |
package com.zaiae.design.pattern.creational.factorymethod; public abstract class Video { public abstract void produce(); } |
JavaVideo.java
Java视频类,继承视频抽象类,并实现自己的生产视频逻辑。
1 2 3 4 5 6 7 8 9 |
package com.zaiae.design.pattern.creational.factorymethod; public class JavaVideo extends Video { @Override public void produce() { System.out.println("录制一套Java课程视频"); } } |
PythonVideo.java
Python视频类,继承视频抽象类,并实现自己的生产视频逻辑。
1 2 3 4 5 6 7 8 9 |
package com.zaiae.design.pattern.creational.factorymethod; public class PythonVideo extends Video { @Override public void produce() { System.out.println("录制一套Python课程视频"); } } |
VideoFactory.java
生产视频的工厂方法基类,只定义规范和契约。我们该使用抽象类还是接口,需要根据实际需求来确定。
1 2 3 4 5 |
package com.zaiae.design.pattern.creational.factorymethod; public abstract class VideoFactory { public abstract Video getVideo(); } |
JavaVideoFactory.java
生产Java视频的工厂方法类,创建需要的对象。
1 2 3 4 5 6 7 8 |
package com.zaiae.design.pattern.creational.factorymethod; public class JavaVideoFactory extends VideoFactory { @Override public Video getVideo() { return new JavaVideo(); } } |
PythonVideoFactory.java
生产Python视频的工厂方法类,创建需要的对象。
1 2 3 4 5 6 7 8 |
package com.zaiae.design.pattern.creational.factorymethod; public class PythonVideoFactory extends VideoFactory { @Override public Video getVideo() { return new PythonVideo(); } } |
Test.java
客户端(应用层)调用工厂方法,创建需要的对象。
1 2 3 4 5 6 7 8 9 10 11 12 |
package com.zaiae.design.pattern.creational.factorymethod; public class Test { public static void main(String[] args) { VideoFactory videoFactory = new JavaVideoFactory(); videoFactory.getVideo().produce(); VideoFactory videoFactory1 = new PythonVideoFactory(); videoFactory1.getVideo().produce(); } } |
UML结构图:

JDK中的使用例子
例如在 java.util.Collection
接口中的 Iterator<E> iterator()
方法,就是一个工厂方法。
在具体的实现工厂 java.util.ArrayList
中重写 Iterator<E> iterator()
方法,用于创建 Iterator
实例对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
public Iterator<E> iterator() { return new 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(); } } |