定义
定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行,光看定义肯定还不够明白到底是什么意思,别急,下面我们会用代码来告诉你工厂方法到底是怎么个一回事,我们先看看它的优缺点及使用场景
优点
- 完全符合开闭原则,对扩展是开放的,对修改是关闭的
- 用户/应用层/客户端不再关心对象具体的实例化,其中具体细节对用户隐藏,很大程度上进行了代码的解耦
缺点
- 类的个数容易过多,增加复杂度
- 增加了系统的抽象性和理解难度
适用场景
- 需要使用大量new的重复代码
- 多个同一产品等级的产品创建需求
这里解释一下什么是产品等级和产品族,我们拿电子产品来举例
手机、电脑、智能手环等都是电子产品,不同的电子产品有不同的产商
例如:华为电脑、苹果电脑、小米电脑是属于同一产品等级的,都是电脑
例如:华为电脑、华为手机、华为手环都是华为的,它们是属于同一产品族的
工厂方法适合用于单一产品等级的创建
抽象工厂适合用于同一产品族的创建
下面,我们用具体的示例代码来描述工厂方法
我用一个我常用的学习网站,慕课网来举例进行说明。
慕课网中有许多的学习视频,例如Java视频,FE视频,Python视频
(ps:爆吹一下7七月老师与geely老师,都是大牛级别的)
我们先创建一个Video的接口,里面只有一个方法
//这里用抽象类或接口都可以,不过抽象类不仅有抽象方法,还可以有自己的实例方法
/**
* 这里只有一个方法,就是produce,用于生产视频的,至于生产什么视频,由实现这个
* 接口的类来决定
**/
public interface Video {
void produce();
}
接着我们再创建一个JavaVideo的类,来实现Video的方法
public class JavaVideo implements Video {
@Override
public void produce() {
System.out.println("录制Java课程视频");
}
}
然后我们创建一个Video的工厂类,它是一个接口
/**
* 为什么它是一个接口,而不是一个class,因为我们前面在定义中已经说了
* 工厂方法让类的实例化推迟到子类中进行,它只负责获取视频
* 返回的是一个Video,获取Video肯定要返回一个Video嘛,至于返回什么样的Video,由它的实现类来决定
*/
public interface VideoFactory {
Video getVideo();
}
好了,接下来我们就要创建把对象new出来的工厂了,先来一个Java吧
public class JavaVideoFactory implements VideoFactory {
@Override
public Video getVideo() {
return new JavaVideo();
}
}
实际上到这里,我们的工厂方法就已经写完了,我们再来梳理一下
首先,有一个Video的接口类,然后有一个JavaVideo来实现Video接口里面的方法,JavaVideo就是具体的Video,然后有一个Video的工厂类,但是它不负责生产Video,具体的生产交由它的实现类来完成。我打个更容易理解的比方
你是一个老板,你需要视频,但是你不会生产视频,所以,你找到生产视频的工厂,然后人家问你,你需要什么视频啊,你说:我需要Java视频,然后视频工厂就找到了Java视频工厂生产了一个Java视频给你
下面看看测试代码,编写一个main方法
public static void main(String[] args) {
//你要Java视频,人家就给你找了Java视频工厂
VideoFactory videoFactory = new JavaVideoFactory();
//Java视频工厂给你生产了一个Java视频交给你
Video video = videoFactory.getVideo();
//然后你拿回去干啥都行啊
video.produce();
}
最后我们说说为什么工厂方法符合开闭原则,如果你需要其它的视频,那么你只需要新建一个具体的视频类实现Video的方法,然后再创建一个对应的工厂类来实现VideoFactory接口中的方法,最后去调用就可以了,这些都是新增、扩展的,而没有对原有的代码进行修改,符合了对扩展开发,对修改关闭的理念。
从这里我们能看出简单工厂与工厂方法的区别了,简单工厂里面只有一个工厂类,里面负责创建所需的各种对象
而工厂方法不同,它有两个工厂的类,一个是接口,一个是接口的子类,或者叫实现类更合适,再回顾一下定义里的那句话,具体的实例化交由它的子类去完成,你要什么,就创建什么工厂。
要Java视频就创建Java视频工厂,你要MacBookPro你就创建一个MacBookPro的工厂
代码已同步码云,点击即可跳转过去