设计模式之工厂模式
一、简单工厂模式
简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由
一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
定义一个工厂类,他可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。
1. 模拟代码(以课件为例)
1. 定义课件ICourse接口类,用来定义产品都需要实现的接口
public interface ICourse {
public void record();
}
2. 定义具体的产品并实现定义的课件接口,这里以java和python课件为例
public class JavaCourse implements ICourse {
@Override
public void record() {
System.out.println("录制java课程");
}
}
public class PythonCourse implements ICourse {
@Override
public void record() {
System.out.println("录制python课程");
}
}
3. 定义工厂类,定义根据指定课件名称创建具体课件的接口
public class CourseFactory{
public ICourse create(Class<? extends ICourse> className){
// 以上逻辑可以通过传对象解决, 可以指定泛型解决强转问题
try {
return className.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}
4. 测试,根据传入课件名称的不同,工厂类会创建不同的课件
public class Test {
public static void main(String[] args) {
// 这里可以传入我们实现课件接口类的某一个具体课件名称,以JavaCourse为例
ICourse course = new CourseFactory().create(JavaCourse.class);
course.record();
}
}
2. 适用场景
1. 工厂类负责创建的对象较少
2. 客户端只需要传入工厂类的参数,对于如何创建对象的逻辑不需要关心
3.优点
1. 只需要传入一个正确的参数,就可以获取你需要的对象,无需知道其创建的细节
4.缺点
1.工厂类的职责相对过重,增加新的产品时需要修改工厂类的判断逻辑,违背开闭原则。模拟代码中利用了反射
技术所以我们新增一个课件产品无需更改,但实际应用中大多数情况需要根据我们参数去判断具体创建哪个课件(产品)。
2.不易于扩展过于复杂的产品解构。
二、简单工厂模式
工厂方法模式(Fatory Method Pattern)是指定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化
到子类中进行。属于创建型设计模式。
1. 模拟代码(以课件为例)
1. 定义课件ICourse接口类,用来定义产品都需要实现的接口
public interface ICourse {
public void record();
}
2. 定义具体的产品并实现定义的课件接口,这里以java和python课件为例
public class JavaCourse implements ICourse {
@Override
public void record() {
System.out.println("录制java课程");
}
}
public class PythonCourse implements ICourse {
@Override
public void record() {
System.out.println("录制python课程");
}
}
3. 定义工厂接口类,定义创建课件的接口
public interface ICourseFactory {
ICourse create();
}
4. 定义java和python课件工厂实现类
public class JavaCourseFactory implements ICourseFactory {
@Override
public ICourse create() {
return new JavaCourse();
}
}
public class PythonCourseFactory implements ICourseFactory {
@Override
public ICourse create() {
return new PythonCourse();
}
}
5. 测试,根据需求创建指定的课件
public class Test {
public static void main(String[] args) {
ICourseFactory factory = new PythonCourseFactory();
ICourse course = factory.create();
course.record();
}
}
2. 适用场景
1. 创建对象需要大量重复代码
2. 客户端(应用层)不依赖于产品类实列如何被创建、实现等细节
3. 一个类通过其子类来指定创建哪个对象
3.优点
1. 用户只需要关心所需产品对应的工厂,无须关心创建细节
2. 加入新产品符合开闭原则,提高了系统的可扩展性
4.缺点
1.类的个数容易过多,增加了代码结构的复杂度。
2.增加了系统的抽象性和理解难度
三、抽象工厂模式
抽象工厂模式(Abstract Factory Pattern)是指提供一个创建一系列相关或相互依赖对象的接口,无须指定他们具体的类。属于创建型设计
模式。
1. 模拟代码(以课件为例,这里定义的每种课件有笔记和视频两种资料,笔记有编辑的功能,视频有录制的功能)
1. 定义笔记编辑和视频录制接口
public interface INote {
void edit();
}
public interface IVideo {
void record();
}
2. 分别定义java和python课件的笔记和视频的实现类
public class JavaNote implements INote{
@Override
public void edit() {
System.out.println("编辑java note");
}
}
public class JavaVideo implements IVideo{
@Override
public void record() {
System.out.println("录制java video");
}
}
public class PythonNote implements INote{
@Override
public void edit() {
System.out.println("编辑python note");
}
}
public class PythonVideo implements IVideo{
@Override
public void record() {
System.out.println("录制python video");
}
}
3. 定义课件的抽象工厂类
public abstract class CourseAbstractFactory {
public void init(){
System.out.println("初始化基础数据");
}
protected abstract INote createNote();
protected abstract IVideo createVide();
}
4. 定义java和python课件工厂类分别继承抽象工厂接
public class JavaCourseFactory extends CourseAbstractFactory {
@Override
protected INote createNote() {
super.init();
return new JavaNote();
}
@Override
protected IVideo createVide() {
super.init();
return new JavaVideo();
}
}
public class PythonCourseFactory extends CourseAbstractFactory {
@Override
protected INote createNote() {
super.init();
return new PythonNote();
}
@Override
protected IVideo createVide() {
super.init();
return new PythonVideo();
}
}
5. 测试。
public class Test {
public static void main(String[] args) {
CourseAbstractFactory courseFactory = new JavaCourseFactory();
courseFactory.createNote().edit();
courseFactory.createVide().record();
}
}
2. 适用场景
1. 客户端(应用层)不依赖于产品类实列如何被创建、实现等细节
2. 强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码
3. 提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现
3.优点
1. 具体产品在应用层代码隔离,无须关心创建细节
2. 将一个系列的产品族统一放到一起创建
4.缺点
1.规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口
2.增加了系统的抽象性和理解难度