0x01.定义与类型
- 定义:由一个工厂对象决定创建出哪一种产品类的实例。
- 类型:创建型,但不属于GOF23中设计模式。
- 简介:通过一个专门的工厂类来创建其他类,这些被创建的类通常有一个共同的父类或接口。
0x02.适用场景
- 工厂类负责创建的对象比较少
- 客户端(应用层)只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心
0x03.简单工厂的优缺点
- 优点:只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节
- 缺点:工厂类的职责相对过重,增加新的产品,需要修改工厂类的判断逻辑,违背开闭原则
0x04.简单工厂的实线样例
- 假设IT教育课程,具有Java, Python等视频。他们都是视频类的子类,而有单独的视频工厂生产这些课程!
- 课程基类
public abstract class Video { public abstract void produce();}
public class VideoFactory { /** * 每次新增加产品实线会修改代码 * 不符合开闭原则 * @param type * @return */ public Video getVideo(String type) { if ("java".equalsIgnoreCase(type)) { return new JavaVideo(); } else if ("python".equalsIgnoreCase(type)) { return new PythonVideo(); } else return null; } /** * 反射方式实现 * @param clazz * @return */ public Video getVideo(Class clazz) { Video video = null; try { video = (Video) Class.forName(clazz.getName()).newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return video; }}
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 Test {// public static void main(String[] args) {// Video video = new JavaVideo();// video.produce();// } public static void main(String[] args) { VideoFactory videoFactory = new VideoFactory(); Video video1 = videoFactory.getVideo("python"); if (video1 != null) { video1.produce(); } Video video2 = videoFactory.getVideo("java"); if (video2 != null) { video2.produce(); } } /* public static void main(String[] args) { VideoFactory videoFactory = new VideoFactory(); Video video = videoFactory.getVideo(PythonVideo.class); if (video != null) { video.produce(); } }*/}
录制Python课程录制Java课程视频
0x05.UML类图
- 如图uml所示:直接的应用类中并没有于具体实现类的耦合,这样当新增具体实现类时是不需要修改应用层业务逻辑
0x06.源码中的简单工厂
- Calendar.createCalendar():JDK时间处理类
//根据输入参数区分的具体实现if (aLocale.hasExtensions()) { String caltype = aLocale.getUnicodeLocaleType("ca"); if (caltype != null) { switch (caltype) { case "buddhist": cal = new BuddhistCalendar(zone, aLocale); break; case "japanese": cal = new JapaneseImperialCalendar(zone, aLocale); break; case "gregory": cal = new GregorianCalendar(zone, aLocale); break; } }}
- jdbc的Class.forname("com.mysql.driver"):通过每个db推出的不同的驱动,通过反射创建出连接。
0x07.相关代码
简单工厂模式
:https://github.com/sigmako/design-pattern/tree/master/simple-factory
0x08.推荐阅读
慕课网设计模式精讲
: https://coding.imooc.com/class/270.html简单工厂模式
:https://blog.csdn.net/weiwenlongll/article/details/6918164