# 工厂方法模式
关联阅读 李兴华-工厂方法
定义:定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类, 工厂方法让类的实例化推迟到子类进行
类型:创建型
# 适用场景
- 创建对象需要大量重复代码
- 客户端(应用层)不依赖于产品类实例如何被创建,实现等细节
- 一个类通过其子类来指定创建哪个对象
使用多态和里氏替换原则。
# 优点
- 用户只需要关心所需产品对应的工厂,无须关心创建细节
- 加入新产品符合开闭原则,提高可扩展性
# 缺点
- 类的个数容易过多,增加复杂度
- 增加了系统的抽象性和理解难度
# Coding
代码很简单,改造之前简单工厂为工厂方法。创建了抽象类 VideoFactory,具体的课程由专门的课程工厂去创建实例
这里贴一下客户端的使用,使用哪一种课程,则用它的工厂来创建实例即可
public class Test {
public static void main(String[] args) {
VideoFactory factory = new JavaVideoFactory();
Video video = factory.getVideo();
video.produce();
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
# 源码解析 jdk + logback
# java.util.Collection#iterator
java.util.Collection#iterator
方法,对于 ArrayList 的以下方法来说.
就是一个工厂方法模式,因为 iterator 方法的实现类有很多,返回的都是具体集合的 iterator 产品;
在这里对应名词是:
- 抽象产品:工厂方法所创建的接口对象,Iterator
- 产品实现对象:具体的产品实现对象,Itr
- 创建器:声明工厂方法的接口 Collection
- 创建者:具体的创建者对象,返回产品 Iterator
强烈建议,先跟着慕课的课程进度学习,学完之后,再去看李兴华的设计模式课程,收获很大
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
public Iterator<E> iterator() {
return new Itr();
}
/**
* An optimized version of AbstractList.Itr
*/
private class Itr implements Iterator<E> {
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# URLStreamHandlerFactory
package java.net;
public interface URLStreamHandlerFactory {
/**
* Creates a new {@code URLStreamHandler} instance with the specified
* protocol.
*
* @param protocol the protocol ("{@code ftp}",
* "{@code http}", "{@code nntp}", etc.).
* @return a {@code URLStreamHandler} for the specific protocol.
* @see java.net.URLStreamHandler
*/
URLStreamHandler createURLStreamHandler(String protocol);
}
sun.misc.Launcher 类中的 Factory 实现了这个工厂方法
/*
* The stream handler factory for loading system protocol handlers.
*/
private static class Factory implements URLStreamHandlerFactory {
private static String PREFIX = "sun.net.www.protocol";
public URLStreamHandler createURLStreamHandler(String protocol) {
String name = PREFIX + "." + protocol + ".Handler";
try {
Class<?> c = Class.forName(name);
return (URLStreamHandler)c.newInstance();
} catch (ReflectiveOperationException e) {
throw new InternalError("could not load " + protocol +
"system protocol handler", e);
}
}
}
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
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
# slfj 的 ILoggerFactory
org.slf4j.LoggerFactory 类中的 ILoggerFactory,这就是一个工厂方法接口
public static Logger getLogger(String name) {
ILoggerFactory iLoggerFactory = getILoggerFactory();
return iLoggerFactory.getLogger(name);
}
1
2
3
4
5
2
3
4
5