该项目源码地址:https://github.com/lastwhispers/code/tree/master/java-basic/design-pattern
(设计模式相关代码与笔记)
1. 定义
定义一个创建对象的接口,但让实现这个接口的类来决定实例化那个类,工厂方法让类的实例化推迟到子类中进行。
2. 适用场景
- 创建对象需要大量重复的代码
- 应用层不依赖于产品类实例如何被创建、实现等细节
- 一个类通过其子类来指定创建那个对象
3. 类图与角色
工厂方法类图- Product: 定义工厂方法所创建的对象的接口;
- Creator:声明工厂方法,并返回一个Product类型的对象;
- ConcreteProduct:是具体的产品,实现了Product接口;
- ConcreteCreator:是具体的工厂方法,返回一个ConcreteProduct实例。
4. 代码实例
背景:现在慕课网需要录制Java、Python等视频课程
(1)创建抽象视频类,定义具体录制视频课程的公共接口
类图对应的角色Product
public abstract class Video {
public abstract void produce();
}
(2)创建抽象工厂类,定义具体工厂的公共接口
类图对应的角色Creator
public abstract class VideoFactory {
public abstract Video getVideo();
}
(3)创建具体视频类(继承抽象视频类),定义录制的具体视频课程
类图对应的角色ConcreteProduct
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课程");
}
}
(4)创建具体工厂类(继承抽象工厂类),定义创建对应具体视频实例的方法
类图对应的角色ConcreteCreteCreator
public class JavaVideoFactory extends VideoFactory {
public Video getVideo() {
return new JavaVideo();
}
}
public class PythonVideoFactory extends VideoFactory {
public Video getVideo() {
return new PythonVideo();
}
}
(5)创建应用层进行测试
项目结构public class Test {
public static void main(String[] args) {
VideoFactory videoFactory = new PythonVideoFactory();
VideoFactory videoFactory1 = new JavaVideoFactory();
Video video = videoFactory.getVideo();
video.produce();
}
}
测试结果:
测试结果(6)扩展
如果现在需要录制前端课程只需要,添加一个录制前端视频类和一个创建前端视频类的工厂即可。
public class FEVideo extends Video {
@Override
public void produce() {
System.out.println("录制前端课程视频");
}
}
public class FEVideoFactory extends VideoFactory {
public Video getVideo() {
return new FEVideo();
}
}
应用层调用测试
public class Test {
public static void main(String[] args) {
VideoFactory videoFactory = new PythonVideoFactory();
VideoFactory videoFactory1 = new JavaVideoFactory();
VideoFactory videoFactory2 = new FEVideoFactory();
Video video = videoFactory.getVideo();
video.produce();
}
}
查看类图
类图5. 优点
- 用户只需要关心所需产品对应的工厂,无须关系创建细节
- 加入新产品,只需要增加相应的具体产品类和相应的工厂子类即可,符合开闭原则,提高可扩展性
- 每个具体工厂类只负责创建对应的产品,符合单一职责原则
6. 缺点
- 添加新产品时,除了增加新产品类外,还要提供与之对应的具体工厂类,系统类的个数将成对增加,在一定程度上增加了系统的复杂度;同时,有更多的类需要编译和运行,会给系统带来一些额外的开销。
- 由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。
- 一个具体工厂只能创建一种具体产品
7. 总结
工厂模式可以说是简单工厂模式的进一步抽象和拓展,在保留了简单工厂的封装优点的同时,让扩展变得简单,让继承变得可行,增加了多态性的体现。
网友评论