文章目录
声明:
本博客是本人在学习《Java 设计模式精讲》后整理的笔记,旨在方便复习和回顾,并非用作商业用途。
本博客已标明出处,如有侵权请告知,马上删除。
1. 简单工厂讲解
- 定义:由一个工厂对象决定创建出哪一种产品类的实例
- 类型:创建型,但不属于 GOF23 种设计模式
- 适用场景
- 工厂类负责创建的对象比较少
- 客户端(应用层)只知道传入工厂类的参数对于如何创建对象(逻辑)不关心
- 优点:只需要传入一个正确的参数,就可以获取你所需要的对象而无须知道其创建细节
- 缺点:工厂类的职责相对过重,增加新的产品需要修改工厂类的判断逻辑,违背开闭原则
2. 简单工厂 Coding
-
创建一个课程视频抽象类
public abstract class Video { public abstract void product(); }
-
创建两门课程视频继承它
public class JavaVideo extends Video { @Override public void product() { System.out.println("录制Java课程视频"); } }
public class PythonVideo extends Video { @Override public void product() { System.out.println("录制Python的课程视频"); } }
-
创建简单工厂类
public class VideoFactory { public Video getVideo(String type) { if ("Java".equals(type)) { return new JavaVideo(); } else if ("Python".equals(type)) { return new Python(); } return null; } }
-
测试类
public class Test { public static void main(String[] args) { VideoFactory videoFactory = new VideoFactory(); Video video = videoFactory.getVideo("Java"); if (video == null) { return; } video.product(); } }
运行结果:
录制Java课程视频
现在类图如下所示:
但是,如果我们还要录制一个 FE 的前端课程,那么,我们就要对工厂类里面的方法进行扩展,那么这个并不符合开闭原则。
下面我们使用反射对简单工厂类进行改造:
-
修改简单工厂类
public class VideoFactory { 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 Test { public static void main(String[] args) { VideoFactory videoFactory = new VideoFactory(); Video video = videoFactory.getVideo(JavaVideo.class); if (video == null) { return; } video.product(); } }
运行结果:
录制Java课程视频
分析:使用反射对简单工厂进行改造后,是符合开闭原则的,在新增课程视频后,我们只需要传入新的参数,而不需要修改简单工厂类。