工厂方法
定义
定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行,光看定义肯定还不够明白到底是什么意思,别急,下面我们会用代码来告诉你工厂方法到底是怎么个一回事,我们先看看它的优缺点及使用场景
优点
- 完全符合开闭原则,对扩展是开放的,对修改是关闭的
- 用户/应用层/客户端不再关心对象具体的实例化,其中具体细节对用户隐藏,很大程度上进行了代码的解耦
缺点
- 类的个数容易过多,增加复杂度
- 增加了系统的抽象性和理解难度
适用场景
- 需要使用大量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的工厂
代码已同步码云,点击即可跳转过去