一文带你看懂工厂模式

大家好我是mihotel,今天来总结一下设计模式中的工厂模式,在平时编程中,构建对象最常用的方式是 new 一个对象。乍一看这种做法没什么不好,而实际上这也属于一种硬编码。每 new 一个对象,相当于客户端多知道了一个类,增加了类与类之间的联系,不利于程序的松耦合。我们可以利用工厂模式封装对象的生产过程。

简单工厂模式

首先是简单工厂模式,它是通过指定一个工厂对象来创建产品实例,只需要传给工厂参数,不需要关系对象是怎样产生的.
举个例子:如果我们要录制Java和Python两门课程,我们可以先创建ICourse接口, 提供录制功能:

public interface ICourse {
    void record();// 录制
}

然后分别创建JavaCourse类与PythonCourse类

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课程");
    }
}

如果我们不使用工厂模式来创建对象,客户端的代码是这样的:

@Test
public void testFactory01() {
	ICourse java = new JavaCourse();
	java.record();
	ICourse python = new PythonCourse();
	python.record();
}

可以看到客户端直接依赖了JavaCourse对象和PythonCourse对象,随着业务发展耦合度会很高。

下面我们通过简单工厂模式解耦,创建简单工厂模式类:

public class SympleFactory {
    public <T> T getCourse(Class<T> clazz) {
        try {
            return clazz.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }
}

利用简单工厂模式我们再来看看客户端实现,代码如下:

@Test
public void testFactory02() {
    SympleFactory sympleFactory = new SympleFactory();
    JavaCourse java = sympleFactory.getCourse(JavaCourse.class);
    java.record();
    PythonCourse python = sympleFactory.getCourse(PythonCourse.class);
    python.record();
}

可以看到现在客户端只与sympleFactory产生依赖,因此达到了解耦的作用。还需注意到,在SympleFactory中我们使用了反射来创建对象,避免了过多的 if else 语句。

总结一下:

简单工厂模式:

  • 概念:指定一个工厂对象来创建产品实例,只需要传给工厂参数,不需要关系对象是怎样产生的.

  • 好处:如果业务扩展客户端会依赖 “一坨”对象,耦合度高,通过简单工厂模式改造后只依赖工厂类,耦合度降低

  • 缺点:不符合开闭原则,如果增加新的参数则需要修改创建对象的代码

工厂方法模式

可以看到简单工厂模式只适合生产少量的对象,如果生产的对象总类过多,既不符合单一职责原则,也会导致工厂类十分臃肿。工厂方法模式就解决了该问题,通过指定一个创建对象的接口,让实现这个接口的类来决定实例化哪一个类,实例化推迟到子类中进行。

举个例子,要开设多门编程语言课程比如java、python,下面我们用工厂方法模式来生产这些对象,首先定义一个ICourseFactory接口:

public interface ICourseFactory {
    ICourse create();
}

创建java工厂和python工厂:

public class JavaCourseFactory implements ICourseFactory{
    @Override
    public ICourse create() {
        return new JavaCourse();
    }
}

public class PythonFactory implements ICourseFactory {
    @Override
    public ICourse create() {
        return new PythonCourse();
    }
}

再来创建客户端测试类:

@Test
public void testFactory03() {
    ICourseFactory javaCourseFactory = new JavaCourseFactory();
    ICourse java = javaCourseFactory.create();
    java.record();
    ICourseFactory pythonFactory = new PythonFactory();
    ICourse python = pythonFactory.create();
    python.record();
}

可以发现工厂方法模式符合单一职责原则,一个工厂的具体实现类只生产一种产品,并且符合开闭原则,当需要生产新的产品时不需要修改代码,只需要新增一个实现类即可。

总结一下:

工厂方法模式:

  • 概念:指定一个创建对象的接口,让实现这个接口的类来决定实例化哪一个类,实例化推迟到子类中进行。
  • 好处:用户只需要关心生产产品对应的工厂,不需要关系生产产品的细节,符合开闭原则
  • 适用场景:
    1. 创建对象需要大量重复代码
    2. 客户端(应用层)不依赖产品实例如何被创建、如何被实现等细节
    3. 一个类通过其子类来指定创建哪个对象

抽象工厂模式

可以看到工厂方法模式生产是某个产品的专属工厂,而实际情况下我们往往需要生产一个产品类簇,比如空调和空调遥控器就属于一个产品类簇。下面还是举个例子,我们如果要开设编程课程,每门课程不止会有视频,还会有笔记,java课程有对应的视频和笔记,同理python课程也有。下面我们使用抽象工厂模式来生产“视频”和“笔记"这一个类簇的对象。首先创建视频接口和笔记接口:

public interface IVideo {
    void record();// 录制
}
public interface INote {
    void edit();// 编辑
}

然后创建对应的实现类:

public class JavaNote implements INote{
    @Override
    public void edit() {
        System.out.println("java课程笔记");
    }
}
public class JavaVideo implements IVideo{
    @Override
    public void record() {
        System.out.println("录制Java视频");
    }
}

然后我们创建CourseFactory接口作为顶层设计,用来生产”视频“和”笔记“这个产品类簇

public interface CourseFactory {
    INote createNote();
    IVideo createVideo();
}

接下来就是它的实现类:

public class JavaCourseFactory implements CourseFactory{
    @Override
    public INote createNote() {
        return new JavaNote();
    }

    @Override
    public IVideo createVideo() {
        return new JavaVideo();
    }
}

我们来看一下客户端调用:

public void testFactory04() {
    CourseFactory javaCourseFactory = new JavaCourseFactory();
    IVideo javaVideo = javaCourseFactory.createVideo();
    javaVideo.record();
    INote javaNote = javaCourseFactory.createNote();
    javaNote.edit();
}

客户端耦合了JavaCourseFactory,生产了属于一个产品类簇的对象。

总结一下

  • 概念:指定一个接口生产创建一系列产品,或相互依赖的对象。

  • 缺点:

    1. 类的个数容易过多

    2. 增加了系统抽象性和理解难度

    3. 不符合开闭原则,增加产品时从抽象工厂开始都要进行修改

    4. 增加了系统的抽象性和理解难度

到这里工厂模式就讲完了,希望能够帮助到大家。

参考

  • Spring 5 核心原理

  • 深入浅出设计模式


大家好我是mihotel,此次的推文对设计模式中的工厂模式的学习总结,分析了为什么要使用工厂模式以及各工厂模式的优缺点,相信通过对工厂模式的学习利用,大家可以写出更加优雅的代码~大家也可关注公众号【学习休憩站】,不定期分享学习资源。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
责任链设计模式是一种行为型设计模式,用于将请求的发送者和接收者解耦,使多个对象都有机会处理该请求。该模式将这些对象串成链,并沿着这条链传递请求,直到有一个对象能够处理它为止。 责任链模式的核心是定义一个处理请求的抽象类或接口,然后让多个具体的处理者对象继承或实现这个类/接口。每个具体的处理者对象都包含一个对下一个处理者对象的引用,形成一个链式结构。 当一个请求进入责任链时,责任链中的每个处理者都有机会处理该请求。如果可以处理请求,则进行处理;如果不能处理,则将请求传递给下一个处理者,直到有一个处理者能够处理它。 责任链模式的关键点是要找到合适的处理者顺序和条件。通常情况下,责任链模式适用于以下情况: 1. 有多个对象可以处理同一类型的请求,但具体由哪个对象来处理由运行时决定。 2. 不明确请求的接收者,希望请求在一个对象链中流动,直到被处理。 3. 需要动态地指定可以处理请求的对象集合。 使用责任链模式可以实现请求发送者和接收者的解耦,增加代码的灵活性和可扩展性。但同时也需要注意责任链的长度和效率问题,避免责任链过长或造成性能问题。 总结一下,责任链设计模式是一种将请求发送者和接收者解耦的设计模式,通过将多个处理者对象串成链,沿着这条链传递请求,直到有一个处理者能够处理它。这样可以增加代码的灵活性和可扩展性,适用于有多个对象可以处理同一类型请求的情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值