【Spring】工厂模式

简介: 【Spring】工厂模式

根据 【动力节点】最新Spring框架教程,全网首套Spring6教程,跟老杜从零学spring入门到高级 以及老杜的原版笔记 https://www.yuque.com/docs/share/866abad4-7106-45e7-afcd-245a733b073f?# 《Spring6》 进行整理, 文档密码:mg9b


Spring 相关文章整理汇总归纳于:https://www.yuque.com/u27599042/zuisie


  • 设计模式:一种可以被重复利用的解决方案
  • 开发原则,是软件开发的依据,设计模式会尽量满足开发原则
  • GoF(Gang of Four)四人组,在《Design Patterns: Elements of Reusable Object-Oriented Software》(即《设计模式》一书)中描述了23种设计模式,所以一般情况下,GoF就是指23种设计模式
  • 我们平常所说的设计模式就是指《设计模式》一书中描述的23种设计模式
  • 除了GoF23种设计模式之外,还有其它的设计模式,比如:JavaEE的设计模式(DAO模式、MVC模式等)。
  • GoF23种设计模式可以分为三类:
  • 创建型(5个):解决对象创建问题。
  • 其中包含单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式
  • 结构型(7个):一些类或对象组合在一起的经典结构。
  • 行为型(11个):解决类或对象之间的交互问题。
  • 工厂模式是解决对象创建问题的,所以工厂模式属于创建型设计模式。
  • 这是因为Spring框架底层使用了大量的工厂模式。

工厂模式的三种形态

  • 简单工厂模式(Simple Factory):不属于23种设计模式之一。
  • 简单工厂模式又叫做:静态工厂方法模式。
  • 简单工厂模式是工厂方法模式的一种特殊实现。
  • 工厂方法模式(Factory Method):是23种设计模式之一。
  • 抽象工厂模式(Abstract Factory):是23种设计模式之一。

简单工厂模式

  • Spring中的BeanFactory就使用了简单工厂模式。
  • 在简单工厂模式中,工厂类中生产产品的方法为静态方法
  • 简单工厂模式的角色包括三个:
  • 抽象产品 角色
  • 具体产品 角色
  • 工厂类 角色

抽象产品角色

/**
 * ClassName: Weapon
 * Package: simple.cw.spring
 * Description:
 * 抽象产品角色 - 武器抽象类
 *
 * @Author tcw
 * @Create 2023-05-23 20:52
 * @Version 1.0
 */
public abstract class Weapon {
    /**
     * 武器的攻击方法
     */
    public abstract void attack();
}

具体产品角色

/**
 * ClassName: Tank
 * Package: simple.cw.spring
 * Description:
 * 具体产品角色 - 坦克类
 *
 * @Author tcw
 * @Create 2023-05-23 20:55
 * @Version 1.0
 */
public class Tank extends Weapon{
    @Override
    public void attack() {
        System.out.println("开炮!!!!!!");
    }
}
/**
 * ClassName: Fighter
 * Package: simple.cw.spring
 * Description:
 * 具体产品角色 - 飞机类
 *
 * @Author tcw
 * @Create 2023-05-23 20:56
 * @Version 1.0
 */
public class Fighter extends Weapon {
    @Override
    public void attack() {
        System.out.println("投掷炸弹....");
    }
}
/**
 * ClassName: Dagger
 * Package: simple.cw.spring
 * Description:
 * 具体产品角色 - 匕首类
 *
 * @Author tcw
 * @Create 2023-05-23 20:56
 * @Version 1.0
 */
public class Dagger extends Weapon{
    @Override
    public void attack() {
        System.out.println("砍!砍!砍!砍!");
    }
}

工厂类角色

  • 由于简单工厂模式中的工厂类中生产产品的方法为静态方法,所以简单工厂模式又称为静态工厂方法模式
/**
 * ClassName: WeaponFactory
 * Package: simple.cw.spring
 * Description:
 * 工厂类角色 - 武器工厂
 *
 * @Author tcw
 * @Create 2023-05-23 20:58
 * @Version 1.0
 */
public class WeaponFactory {
    /**
     * 根据需要的武器类型创建武器
     *
     * @param weaponType 需要的武器类型
     * @return 需要的武器类型相应的武器对象
     */
    public static Weapon getWeapon(String weaponType) {
        // 将要返回的武器对象
        Weapon weapon = null;
        // 根据需要的武器类型创建武器
        switch (weaponType) {
            case "tank":
                weapon = new Tank();
                break;
            case "fighter":
                weapon = new Fighter();
                break;
            case "dagger":
                weapon = new Dagger();
                break;
        }
        return weapon;
    }
}

客户端程序

  • 对于客户端来说,无需了解产品的具体生产过程,只需直接利用工厂角色进行产品的生产即可
  • 由于客户端无需关心产品的具体生产过程,客户端只需要负责进行消费即可,工厂角色只需根据客户端的需求生产相应的产品即可,即客户端只负责消费,工厂角色只负责生产,使得生产者和消费者分离了
  • 简单工厂模式的作用:使生产者和消费者的职责分离,对方都无需关心对方的具体细节
@org.junit.Test
public void test01() {
    // 利用工厂角色生产产品(生产者生产产品)
    Weapon tank = WeaponFactory.getWeapon("tank");
    Weapon fighter = WeaponFactory.getWeapon("fighter");
    Weapon dagger = WeaponFactory.getWeapon("dagger");
    // 使用武器进行攻击(消费者消费产品)
    tank.attack();
    fighter.attack();
    dagger.attack();
}

简单工厂模式解决的问题(优点)

  • 客户端程序不需要关心对象的创建细节,需要哪个对象时,只需要向工厂索要即可,初步实现了责任的分离。
  • 客户端只负责“消费”,工厂负责“生产”,生产和消费分离。

简单工厂模式的缺点

  • 简单工厂模式不符合OCP开闭原则,因为在系统需要进行扩展时,需要修改原先已经写好的工厂类
  • 工厂类的责任比较重大,不能出现任何问题,因为这个工厂类负责所有产品的生产,称为全能类,或者有人把它叫做上帝类。这个工厂类一旦出问题,整个系统必然全部瘫痪。(不要把所有鸡蛋放到一个篮子里面)

工厂方法模式

  • 工厂方法模式,区别与简单工厂模式,就是一个产品对应一个工厂类
  • 工厂方法模式的角色包括:
  • 抽象工厂角色
  • 具体工厂角色
  • 抽象产品角色
  • 具体产品角色

抽象产品角色

/**
 * ClassName: Weapon
 * Package: simple.cw.spring
 * Description:
 * 抽象产品角色 - 武器抽象类
 *
 * @Author tcw
 * @Create 2023-05-23 20:52
 * @Version 1.0
 */
public abstract class Weapon {
    /**
     * 武器的攻击方法
     */
    public abstract void attack();
}

具体产品角色

/**
 * ClassName: Tank
 * Package: simple.cw.spring
 * Description:
 * 具体产品角色 - 坦克类
 *
 * @Author tcw
 * @Create 2023-05-23 20:55
 * @Version 1.0
 */
public class Tank extends Weapon{
    @Override
    public void attack() {
        System.out.println("开炮!!!!!!");
    }
}
/**
 * ClassName: Fighter
 * Package: simple.cw.spring
 * Description:
 * 具体产品角色 - 飞机类
 *
 * @Author tcw
 * @Create 2023-05-23 20:56
 * @Version 1.0
 */
public class Fighter extends Weapon {
    @Override
    public void attack() {
        System.out.println("投掷炸弹....");
    }
}
/**
 * ClassName: Dagger
 * Package: simple.cw.spring
 * Description:
 * 具体产品角色 - 匕首类
 *
 * @Author tcw
 * @Create 2023-05-23 20:56
 * @Version 1.0
 */
public class Dagger extends Weapon{
    @Override
    public void attack() {
        System.out.println("砍!砍!砍!砍!");
    }
}

抽象工厂角色

/**
 * ClassName: WeaponFactory
 * Package: simple.cw.spring
 * Description:
 * 抽象工厂角色 - 武器工厂
 *
 * @Author tcw
 * @Create 2023-05-23 20:58
 * @Version 1.0
 */
public abstract class WeaponFactory {
    /**
     * 生产武器
     *
     * @return 武器
     */
    public abstract Weapon getWeapon();
}

具体工厂角色

/**
 * ClassName: DaggerFactory
 * Package: simple.cw.spring
 * Description:
 * 具体工厂角色 - 生产匕首的工厂
 *
 * @Author tcw
 * @Create 2023-05-24 18:15
 * @Version 1.0
 */
public class DaggerFactory extends WeaponFactory {
    @Override
    public Weapon getWeapon() {
        return new Dagger();
    }
}
/**
 * ClassName: TankFactory
 * Package: simple.cw.spring
 * Description:
 * 具体工厂角色 - 生产坦克的工厂
 *
 * @Author tcw
 * @Create 2023-05-24 18:18
 * @Version 1.0
 */
public class TankFactory extends WeaponFactory{
    @Override
    public Weapon getWeapon() {
        return new Tank();
    }
}
/**
 * ClassName: FighterFactory
 * Package: simple.cw.spring
 * Description:
 * 具体工厂角色 - 生产飞机的工厂
 *
 * @Author tcw
 * @Create 2023-05-24 18:19
 * @Version 1.0
 */
public class FighterFactory extends WeaponFactory{
    @Override
    public Weapon getWeapon() {
        return new Fighter();
    }
}

客户端程序

@org.junit.Test
public void test01() {
    // 创建工厂类对象
    WeaponFactory tankFactory = new TankFactory();
    WeaponFactory fighterFactory = new FighterFactory();
    WeaponFactory daggerFactory = new DaggerFactory();
    // 利用工厂对象生产产品
    Weapon tank = tankFactory.getWeapon();
    Weapon fighter = fighterFactory.getWeapon();
    Weapon dagger = daggerFactory.getWeapon();
    // 使用武器进行攻击
    tank.attack();
    fighter.attack();
    dagger.attack();
}

工厂方法模式解决的问题(优点)

  • 工厂方法模式,由于一个产品对应一个工厂类,所以在新增产品时,只需要新增一个工厂类和一个具体产品类即可,不用修改原程序,客户端需要新的产品时,只需要调用新的工厂类的相应方法即可,解决了简单工厂模式违背OCP原则的问题;
  • 扩展性高
  • 同时由于一个产品对应一个工厂类,所以工厂也就不是全能类,避免了工厂类一旦出问题导致整个系统必然全部瘫痪的问题
  • 一个调用者想创建一个对象,只要知道其名称就可以了,生产和消费分离。
  • 屏蔽产品的具体实现,调用者只关心产品的接口。

工厂方法模式的缺点

  • 每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。
  • 类爆炸,由于类的个数急剧增多,类之间的关系复杂度也急剧上升,导致系统难维护
  • 工厂方法模式缺点的解决,使用抽象工厂模式
相关文章
|
前端开发 JavaScript Java
浅谈Spring的相关概念性问题 IOC DI AOP 工厂模式 单例
浅谈Spring的相关概念性问题 IOC DI AOP 工厂模式 单例
136 0
|
设计模式 Java Spring
java spring设计模式 之 工厂模式
java spring设计模式 之 工厂模式
|
SQL 人工智能 Java
Spring中使用工厂模式解耦详解
Spring中使用工厂模式解耦详解
|
设计模式 Java Spring
三分钟快速了解Spring中的工厂模式
前言 今天4ye来和小伙伴们分享下设计模式中的工厂模式啦😄 顺便带来了下面三个问题,一起来看看叭😋 一.工厂模式 我们都知道,设计模式有23种,按照功能和使用场景可以分为三大类: • 创建型模式 • 结构型模式 • 行为型模式 工厂设计模式(Factory Pattern)呢,就是一种很常见的设计模式,属于创建型模式的,主要作用就是来创建对象的~
204 0
|
设计模式 缓存 Java
使用Spring的BeanPostProcessor优雅的实现工厂模式
使用Spring的BeanPostProcessor优雅的实现工厂模式
|
Java vr&ar Spring
源码专题之spring设计模式:委派模式、工厂模式
委派模式 在常见的23种设计模式中其实并没有委派模式的影子,但是委派模式确实是spring中应用比较多的一种,SpringMVC框架中的DispatcherServlet就是用到了这种模式。下面以项目经理和普通员工的模型来实现一个简单的委派模式。
4244 0
|
6天前
|
SQL 监控 druid
springboot-druid数据源的配置方式及配置后台监控-自定义和导入stater(推荐-简单方便使用)两种方式配置druid数据源
这篇文章介绍了如何在Spring Boot项目中配置和监控Druid数据源,包括自定义配置和使用Spring Boot Starter两种方法。
|
2月前
|
缓存 Java Maven
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决
|
3月前
|
Java 测试技术 数据库
Spring Boot中的项目属性配置
本节课主要讲解了 Spring Boot 中如何在业务代码中读取相关配置,包括单一配置和多个配置项,在微服务中,这种情况非常常见,往往会有很多其他微服务需要调用,所以封装一个配置类来接收这些配置是个很好的处理方式。除此之外,例如数据库相关的连接参数等等,也可以放到一个配置类中,其他遇到类似的场景,都可以这么处理。最后介绍了开发环境和生产环境配置的快速切换方式,省去了项目部署时,诸多配置信息的修改。
|
3月前
|
Java 应用服务中间件 开发者
Java面试题:解释Spring Boot的优势及其自动配置原理
Java面试题:解释Spring Boot的优势及其自动配置原理
101 0
下一篇
无影云桌面