【学习笔记】慕课网—Java设计模式精讲 第5章 工厂方法模式
/**
* 工厂方法模式 学习笔记
* @author cnRicky
* @date 2018.11.12
*/
工厂方法模式
工厂方法-定义与类型
-
定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让这个类的实例化推迟到子类中进行
- 创建对象的任务就委托给了多个工厂子类中的某一个
- 客户端在使用时无须关心是哪个工厂子类产品的产品子类
- 需要的时候再动态指定就可以了
- 如果需要动态指定,还可以把工厂类的类名存储在配置文件或者数据库中进行动态创建
-
类型:创建型
-
两个关键词:工厂、方法
- 工厂:用来创建对象
- 方法:通过子类实现方法来创建对象
工厂方法-适用场景
- 创建对象需要大量重复的代码
- 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节一个类通过子类来指定创建哪个对象
- 具体的产品对象由具体的工厂类来创建,客户端不需要知道具体产品类的类名
- 客户端只需要了解我要的产品在哪个工厂里
工厂方法-优点
- 用户只需关心所需产品对应的工厂,无须关心创建细节加入新产品符合开闭原则,提高可扩展性
- 基于工厂角色和产品角色的多态性设计是工厂方法模式的关键
- 可以使工厂自主确定创建何种产品对象
- 而如何创建这个对象的细节则被封装在具体的工厂内部
工厂方法-缺点
- 类的个数容易过多,增加复杂度增加了系统的抽象性和理解难度
- 类的个数增加的原因:在添加新产品的时候要添加新的产品类,而且还要提供与此产品类对应的工厂类
- 类的个数增加了,系统的复杂度也就增加了
代码实例:
Video抽象类:
public abstract class Video {
abstract public void produce();
}
FEVideo类:
public class FEVideo extends Video {
//现在,具体产生什么类型的视频,由VideoFactory的子类来决定
//而不需要VideoFactory自己来决定,VideoFactory类只规定了一个规范
@Override
public void produce() {
System.out.println("录制前端课程视频");
}
}
JavaVideo类:
public class JavaVideo extends Video{
//现在,具体产生什么类型的视频,由VideoFactory的子类来决定
//而不需要VideoFactory自己来决定,VideoFactory类只规定了一个规范
@Override
public void produce() {
System.out.println("正在录制Java视频");
}
}
PythonVideo类:
public class PythonVideo extends Video {
//现在,具体产生什么类型的视频,由VideoFactory的子类来决定
//而不需要VideoFactory自己来决定,VideoFactory类只规定了一个规范
@Override
public void produce() {
System.out.println("正在录制Python视频");
}
}
VideoFactory抽象类:
public abstract class VideoFactory{
//现在,VideoFactory只指定规范,契约
//产生哪一类型视频的任务由VideoFactory的子类来实现
public abstract Video getVideo();
}
FEVideoFactory类:
public class FEVideoFactory extends VideoFactory {
@Override
public Video getVideo() {
return new FEVideo();
}
}
JavaVideoFactory类:
public class JavaVideoFactory extends VideoFactory {
@Override
public Video getVideo() {
return new JavaVideo();
}
}
PythonVideoFactory类:
public class PythonVideoFactory extends VideoFactory {
@Override
public Video getVideo() {
return new PythonVideo();
}
}
Test(应用层)类:
public class Test {
public static void main(String[] args) {
VideoFactory videoFactory1 = new JavaVideoFactory();//父类声明的引用指向子类的一个实现
VideoFactory videoFactory2 = new PythonVideoFactory();
VideoFactory videoFactory3 = new FEVideoFactory();
Video video = videoFactory1.getVideo();
video.produce();
}
}
代码UML图: