只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节
工厂类的职责相对过重,增加新的产品,需要修改工厂类的判断逻辑,违背开闭原则
创建一个抽象产品类
public abstract class Video {
public abstract void produce();
}
产品实现类
public class JavaVideo extends Video {
@Override
public void produce() {
System.out.println("录制Java课程");
}
}
public class PythonVideo extends Video {
@Override
public void produce() {
System.out.println("录制Python视频");
}
}
创建产品对应的简单工厂,通过产品类型来创建产品,应用方无需知道创建产品的细节
public class VideoFactory {
public Video getVideo(String type) {
if ("java".equalsIgnoreCase(type)) {
return new JavaVideo();
} else if ("python".equalsIgnoreCase(type)) {
return new PythonVideo();
} else {
return null;
}
}
}
测试类
public class Test {
public static void main(String[] args) {
VideoFactory videoFactory = new VideoFactory();
Video video = videoFactory.getVideo("Java");
video.produce();
}
}
控制台输出
录制Java课程
如果增加产品,我们不仅需要修改产品对应的产品类,还需要修改工厂类,违反了开闭原则。
我们可以通过反射来优化下我们的工厂类
public class VideoFactory {
public Video getVideo(Class<? extends Video> clazz) {
try {
return clazz.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}
这样一来,添加产品的时候不用再修改我们的工厂类,而是直接添加产品即可。
最终的UML类图

JDK源码在JDK中,使用简单工厂模式的例子如java.util.Calendar,一组getInstance的重载方法,提供了创建Calendar产品的简单工厂方法。
public static Calendar getInstance()
public static Calendar getInstance(TimeZone zone)
public static Calendar getInstance(Locale aLocale)
public static Calendar getInstance(TimeZone zone,Locale aLocale)
核心方法为
private static Calendar createCalendar(TimeZone zone,Locale aLocale)
源码较长,不贴了,有兴趣的可以去看下源码。
Calendar的UML类图如下

Logback源码logback类中的简单工厂模式主要体现在ch.qos.logback.classic.LoggerContext#getLogger(String)
@Override
public final Logger getLogger(final String name) {
if (name == null) {
throw new IllegalArgumentException("name argument cannot be null");
}
// 判断log类型返回root节点的logger
if (Logger.ROOT_LOGGER_NAME.equalsIgnoreCase(name)) {
return root;
}
int i = 0;
Logger logger = root;
// 如果缓存中已经存在的指定的logger,直接返回childLogger
Logger childLogger = (Logger) loggerCache.get(name);
// if we have the child, then let us return it without wasting time
if (childLogger != null) {
return childLogger;
}
// 以下是创建logger的逻辑
String childName;
while (true) {
int h = LoggerNameUtil.getSeparatorIndexOf(name, i);
if (h == -1) {
childName = name;
} else {
childName = name.substring(0, h);
}
// move i left of the last point
i = h + 1;
synchronized (logger) {
childLogger = logger.getChildByName(childName);
if (childLogger == null) {
childLogger = logger.createChildByName(childName);
loggerCache.put(childName, childLogger);
incSize();
}
}
logger = childLogger;
if (h == -1) {
return childLogger;
}
}
}
是一个典型的简单工厂方法
原文:https://www.cnblogs.com/gcdd/p/12292126.html