Java设计模式中的工厂模式详解

 更新时间:2023年09月14日 09:21:05   作者:十维豆脑  
这篇文章主要介绍了Java设计模式中的工厂模式详解,工厂方法模式(Factory Method Pattern):创新型模式之一,简称工厂模式,通过定义工厂父类负责定义创建对象的公共接口,而子类则负责生成具体的对象,需要的朋友可以参考下

一、定义

工厂方法模式(Factory Method Pattern):创新型模式之一,简称工厂模式,通过定义工厂父类负责定义创建对象的公共接口,而子类则负责生成具体的对象

二、UML类图

在这里插入图片描述

三、角色职责

  • 抽象产品(Product):它是定义产品的接口,是工厂方法模式所创建对象的超类型,也就是产品对象的公共父类。
  • 具体产品(Concrete Product):它实现了抽象产品接口,某种类型的具体产品由专门的具体工厂创建,具体工厂和具体产品之间一一对应。
  • 抽象工厂(Factory):在抽象工厂类中声明了工厂方法(Factory Method),用于返回一个产品。抽象工厂是工厂方法模式的核心,所有创建对象的工厂类都必须实现该接口。
  • 具体工厂(Concrete Factory):它是抽象工厂类的子类,实现了在抽象工厂中声明的工厂方法,并可由客户端调用,返回一个具体产品类的实例。

四、代码实现

前言:在简单工厂模式中,我们每需要增加一个品牌的篮球,就需要修改一次工厂,非常麻烦且复杂,违背了开闭原则。在工厂方法模式中,这个缺陷得到了修复。我们将篮球工厂作为一个抽象工厂,每个品牌的篮球工厂去实现这个抽象工厂,篮球对象的创建由每个工厂去负责,当我们需要新的品牌的篮球时,只需要添加篮球工厂与篮球产品即可,提高了程序的扩展性。

抽象篮球接口(抽象产品类 abstract Product)

public interface BasketBall {
    void shot();
}

阿迪达斯篮球(具体产品类 Concrete Product)

public class AdidasBasketBall implements BasketBall {
    @Override
    public void shot() {
        System.out.println("使用阿迪达斯篮球投篮");
    }
}

耐克篮球(具体产品类 Concrete Product)

public class NikeBasketBall implements BasketBall {
    @Override
    public void shot() {
        System.out.println("使用耐克篮球投篮");
    }
}

斯伯丁篮球(具体产品类 Concrete Product)

public class SpaldingBasketBall implements BasketBall {
    @Override
    public void shot() {
        System.out.println("使用斯伯丁篮球投篮");
    }
}

抽象篮球工厂接口(抽象工厂类 Factory)

public interface BasketBallFactory {
    public BasketBall make();
}

阿迪达斯篮球工厂(具体工厂类 Concrete Factory)

public class AdidasBasketBallFactory implements BasketBallFactory {
    @Override
    public BasketBall make() {
        return new AdidasBasketBall();
    }
}

耐克篮球工厂(具体工厂类 Concrete Factory)

public class NikeBasketBallFactory implements BasketBallFactory {
    @Override
    public BasketBall make() {
        return new NikeBasketBall();
    }
}

斯伯丁篮球工厂(具体工厂类 Concrete Factory)

public class SpaldingBasketBallFactory implements BasketBallFactory {
    @Override
    public BasketBall make() {
        return new SpaldingBasketBall();
    }
}

测试类

public class FactoryMethodTest {
    public static void main(String[] args) {
        // 使用阿迪达斯篮球投篮
        BasketBallFactory adidasBasketBallFactory = new AdidasBasketBallFactory();
        adidasBasketBallFactory.make().shot();
        // 使用耐克篮球投篮
        BasketBallFactory nikeBasketBallFactory = new NikeBasketBallFactory();
        nikeBasketBallFactory.make().shot();
        // 使用斯伯丁篮球投篮
        BasketBallFactory spaldingBasketBallFactory = new SpaldingBasketBallFactory();
        spaldingBasketBallFactory.make().shot();
    }
}

五、源码分析

工厂方法模式应用的地方非常广泛,在Spring中就有很多使用了工厂方法模式的地方。

在这里插入图片描述

其中AbstractApplicationContext就是ApplicationContext接口的实现抽象类。

在这里插入图片描述

AbstractApplicationContext的子类AbstractRefreshableApplicationContext就实现了这个抽象方法,使用了这个工厂方法去创建了实例。

这样类的设计与真正的实现之间其实是松耦合的,也正好符合了设计的开闭原则。

六、优缺点分析

优点

  • 用户只需要关心所需产品对应的工厂,无需关心创建细节。
  • 加入新产品 时, 只需要添加一个具体工厂和具体产品 , 提高可扩展性,符合开闭原则。
  • 工厂方法模式中 , 使用工厂类创建产品对象 , 同时隐藏了具体的产品类被实例化的细节 。

缺点

  • 在添加新产品时 , 除了编写新的产品类 , 还要编写该产品类对应的工厂类,增加系统复杂度。

七、适用场景

在日志记录与访问的数据库未知时,会有较多的适用。

客户端对需要对象的类未知时,抽象工厂类通过其子类来指定创建哪个对象。

通过多态性,在程序运行时子类覆盖父类对象,从而使得系统更容易扩展。

八、总结

工厂方法模式中核心的工厂类不再负责对相应子类的创建,而是声明一个子工厂类必须实现的接口,具体的实例化工作由子工厂类去做,提高了程序的扩展性,符合开闭原则。

但在新增一个新产品时,就要新增一个具体工厂和一个具体产品,会增加代码量。

工厂方法模式克服了简单工厂违背开放闭原则的缺点,又保持了封装对象创建过程的优点。

到此这篇关于Java设计模式中的工厂模式详解的文章就介绍到这了,更多相关Java工厂模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • String concat(String str)使用小结

    String concat(String str)使用小结

    这篇文章主要介绍了String concat(String str)使用小结,在了解concat()之前,首先需要明确的是String的两点特殊性,一是长度不可变二是值不可变,本文给大家详细讲解,需要的朋友可以参考下
    2022-11-11
  • 详解Java拦截器以及自定义注解的使用

    详解Java拦截器以及自定义注解的使用

    这篇文章主要为大家介绍了Java拦截器以及自定义注解的使用,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助<BR>
    2021-12-12
  • springboot实现配置本地访问端口及路径

    springboot实现配置本地访问端口及路径

    这篇文章主要介绍了springboot实现配置本地访问端口及路径,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • java使用ZipInputStream实现读取和写入zip文件

    java使用ZipInputStream实现读取和写入zip文件

    zip文档可以以压缩格式存储一个或多个文件,本文主要为大家详细介绍了java如何使用ZipInputStream读取Zip文档与写入,需要的小伙伴可以参考下
    2023-11-11
  • IDEA Maven Mybatis generator 自动生成代码(实例讲解)

    IDEA Maven Mybatis generator 自动生成代码(实例讲解)

    下面小编就为大家分享一篇IDEA Maven Mybatis generator 自动生成代码的实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2017-12-12
  • 一文让你彻底学会Java左移、右移操作

    一文让你彻底学会Java左移、右移操作

    这篇文章主要介绍了了Java中的位运算符,包括左移(<<)、右移(>>)和无符号右移(>>>),左移将数字的二进制位向左移动,相当于乘以2的n次方;右移将数字的二进制位向右移动,保留符号位,相当于除以2的n次方,文中介绍的非常详细,需要的朋友可以参考下
    2025-02-02
  • java同一个类中,一个无事务方法调用一个有事务方法时,事务失效问题

    java同一个类中,一个无事务方法调用一个有事务方法时,事务失效问题

    本文详细介绍了Spring框架中事务管理的实现原理,包括@Transactional注解的使用、事务的开启、提交和回滚机制,以及代理对象的两种实现方式(JDK动态代理和CGLIB代理),文章还探讨了在同一个类中调用有事务方法时事务失效的原因,并提供了解决方法
    2024-12-12
  • Java中Integer和int的区别解读

    Java中Integer和int的区别解读

    这篇文章主要介绍了Java中Integer和int的区别解读,大家都知道他可以表示一个整数,而且也知道可以表示整数的还有int,只是使用Integer的次数要比int多得多,今天我们就来好好探究一下Integer与int的区别以及更深处的知识,需要的朋友可以参考下
    2023-12-12
  • Springboot集成Mybatis-plus、ClickHouse实现增加数据、查询数据功能

    Springboot集成Mybatis-plus、ClickHouse实现增加数据、查询数据功能

    本文给大家讲解Springboot + mybatis-plus 集成ClickHouse,实现增加数据、查询数据功能,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2024-08-08
  • Java通过卖票理解多线程

    Java通过卖票理解多线程

    本文主要介绍了一个多线程卖票的例子,通过卖票这个实例来介绍多线程的方式,加深理解,需要的朋友可以参考下
    2017-09-09

最新评论