本篇主要是简单工厂模式、工厂方法模式和抽象工厂方法模式的学习总结
一.简单工厂模式
1.定义
由一个工厂对象决定创建哪种产品的实例
属于创建型模式,但它不属于23种设计模式之一
2.实现
首先抽象出一个顶层接口(这里课程的行为我们先不管它,不是重点)
public interface ICourse {
}
创建一个JavaCourse类,实现ICourse接口
public class JavaCourse implements ICourse{
}
创建一个PythonCourse类,实现ICourse接口
public class PythonCourse implements ICourse{
}
创建课程工厂类,由它来创建课程
这里我们直接通过反射来创建对象,写法优雅,也可以避免传参传错,参数限制了必须是实现了ICourse接口的类
public class CourseFactory {
public ICourse create(Class<? extends ICourse> clazz) {
try {
return clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}
测试类我们通过工厂类去创建对象,而不是直接new一个课程出来。
public class Test {
public static void main(String[] args) {
ICourse course = new CourseFactory().create(JavaCourse.class);
System.out.println(course);
}
}
3.简单工厂模式在源码中的应用
Calendar
4.简单工厂模式适用场景
工厂类负责创建的对象不多
客户端不需要关心如何创建产品,只需要传入工厂类的参数
二.工厂方法模式
1.定义
定义一个创建对象的接口,由这个接口的实现来决定实例化哪个类。简单来说就是对工厂再进行抽象,创建了一个顶层工厂接口。
它属于创建型模式。
2.实现
定义一个工厂方法接口
public interface ICourseFactory {
ICourse create();
}
定义一个Java课程工厂,实现ICourseFactory接口,它只负责创建java课程
public class JavaCourseFactory implements ICourseFactory{
public ICourse create() {
return new JavaCourse();
}
}
定义一个Python课程工厂,实现ICourseFactory接口,它只负责创建python课程
public class PythonCourseFactory implements ICourseFactory{
public ICourse create() {
return new PythonCourse();
}
}
其他的ICouse、JavaCourse、PythonCourse设计同简单工厂模式。
测试类如下
public class Test {
public static void main(String[] args) {
ICourse javaCourse = new JavaCourseFactory().create();
System.out.println(javaCourse);
}
}
3.工厂方法模式在源码中的应用
ILoggerFactory、Logger
4.工厂方法模式的适用场景
客户端不需要知道对象的创建细节,一个类通过其子类来创建对象。
创建的对象不宜过多,否则会产生大量的工厂类
三.抽象工厂模式
1.定义
提供一系列相关对象的接口,无须指定具体的类
属于创建型模式
为了便于理解我们引入产品族和产品等级结构图
产品等级结构:一组相同产品等级结构的产品可以用工厂方法模式,比如美的冰箱、美的洗衣机、美的空调
产品族:用抽象工厂表示,如海尔、格力、美的
它和工厂方法模式的区别就是工厂又产生了很多行为,这些行为产生了不同的对象
2.实现
ICourse、JavaCourse、PythonCourse写法同简单工厂模式
不管是Java课程还是Python课程都会有笔记和教学视频,这时候Java课程工厂和Python课程工厂就是产品族,它们的属性就是产品等级结构。
创建抽象笔记接口(为了简单起见我们先不写它具体的行为)
public interface INote {
}
创建抽象视频接口
public interface IVideo {
}
创建JavaNote实现INote
public class JavaNote implements INote {
}
创建JavaVideo实现IVideo
public class JavaVideo implements IVideo {
}
创建PythonNote实现INote
public class PythonNote implements INote {
}
创建PythonVideo实现IVideo
public class PythonVideo implements IVideo{
}
这个时候我们对工厂方法的顶层接口进行改造,使它具有创建具体对象行为的能力
public interface ICourseFactory {
void init();
INote createNote();
IVideo createVideo();
}
创建JavaCourseFactory实现ICourseFactory
public class JavaCourseFactory implements ICourseFactory{
public void init() {
}
public INote createNote() {
return new JavaNote();
}
public IVideo createVideo() {
return new JavaVideo();
}
}
创建PythonCourseFactory实现ICourseFactory
public class PythonCourseFactory implements ICourseFactory{
public void init() {
}
public INote createNote() {
return new PythonNote();
}
public IVideo createVideo() {
return new PythonVideo();
}
}
再来看一下客户端代码
public class Test {
public static void main(String[] args) {
JavaCourseFactory javaCourseFactory = new JavaCourseFactory();
javaCourseFactory.init();
javaCourseFactory.createNote();
javaCourseFactory.createVideo();
}
}
我们创建了一个Java课程工厂,它创建了Java课程以及课程应该有的属性或者说是行为。
最后再来看一下类图
3.抽象工厂模式的使用场景
客户端不依赖产品的具体实现细节,提供一个产品类的库,所以的产品以相同的接口创建。
需要注意的是抽象工厂模式容易产生大量的类,给代码阅读增加了难度,如果需要增加产品体系结构就需要修改抽象工厂类,不符合开闭原则。
4.抽象工厂模式在源码中的应用
Pool、AbstractFactory