03_Spring_Bean专题

在说Bean之前,我们先对工厂模式有个简单的认识,把这一部分的知识做一个铺垫。后面我们说到Spring Bean的管理会用来到这个模式。

一、工厂模式

工厂模式是一种设计模式,那设计模式又是什么呢?

简单来说,设计模式,它是一种可以被重复利用的解决方案。1995年《设计模式》由由Erich Gamma,Richard Helm,Ralph Johnson和John Vlissides合著,这四位作者被称为“四人组”(GoF,Gang of Four)。

在书中描述了23种设计模式,因为“四人组”当时出书时间比较早,如果到现在来说应该还会有一些书中没有纳入的新的设计模式。当我们平时说的设计模式就是指的这23种设计模式了。

GoF23种设计模式又可以分为三大类:

1、解决对象创建问题的(创建型),有5个

单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式

2、一些数或者是对象组装在一起的经典结构(结构型),有7个

代理模式、装饰模式、适配器模式、组合模式、享元模式、外观模式、桥接模式

3、解类或者是对象之前交互问题(行为型)

策略模式、模式方法模式、观察者模式、责任链模式、迭代子模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式

现在我们要说的是工厂模式,它是用来解决创建问题的,我们的Bean产生不就是要重点解决谁帮我们创建对象,谁帮我们维护各个对象之间的关系吗?所以Spring底层使用了大量的工厂模式。

工厂模式的三种形态

  • 简单工厂模式:它不属于23种设计模式之一。简单工厂模式又叫静态工厂方法模式,它是工厂方法模式的一种特殊实现
  • 工厂方法模式
  • 抽象工厂模式

接下来我们对这三种形态做进一步的了解

简单工厂模式

对于简单工厂模式来说,它分为三个角色:抽象产品角色、具体产品角色、工厂类角色

下面我们用实际的代码来说明

抽象产品角色,它是对具体的各个产品的行为特征的抽象,它是不能产生具体的对象(或者说产品的)

/**
 * 抽象产品角色
 */
public abstract class Weapon {

    /**
     * 所有武器都有攻击的行为
     */
    public abstract void attack();
}

具体产品角色,它就是实实在在在描最终要生产的对象/产品,一般来说具体产品角色是会有多个的,下面有三个类,它们都是具象化的具体产品描述。

/**
 * 具体产品角色
 */
public class Tank extends Weapon {
    @Override
    public void attack() {
        System.out.println("坦克开炮~");
    }
}


/**
 * 具体产品角色
 */
public class Fighter extends Weapon {
    @Override
    public void attack() {
        System.out.println("战斗机投下导弹~");
    }
}


/**
 * 具体产品角色
 */
public class Dagger extends Weapon {
    @Override
    public void attack() {
        System.out.println("匕首攻击~");
    }
}

工厂类角色,这个角色就是具体来为我们提供对象的,工厂嘛肯定是生产产品的地方

/**
 * 工厂类角色
 */
public class WeaponFactory {
    /**
     * 根据不同的武器类型,返回不同的武器对象
     * @param weaponType
     * @return
     */
    public static Weapon get(String weaponType) {
        if (weaponType == null || weaponType.trim().isEmpty()) {
            throw new RuntimeException("要生产生什么武器,请先告诉我~~");
        }
        Weapon weapon = switch (weaponType) {
            case "TANK" -> new Tank();
            case "FIGHTER" -> new Fighter();
            case "DAGGER" -> new Dagger();
            default -> throw new RuntimeException("不支持生产该武器~~");
        };
        return weapon;
    }
}

当我们要使用具体产品/对象的时候,我们不直接new了(对象是怎么生产出来的,怎和new的,有没有一些复杂的逻辑都不管了),而是让这个工厂帮我们去生产,我们只需要告诉它我们的需求即可。如下所示的客户端代码

public class Client {
    public static void main(String[] args) {
        Weapon weapon1 = WeaponFactory.get("TANK");
        weapon1.attack();

        Weapon weapon2 = WeaponFactory.get("FIGHTER");
        weapon2.attack();

        Weapon weapon3 = WeaponFactory.get("DAGGER");
        weapon3.attack();
    }
}

上面这种就是简单工厂模式,这种模式的优缺点如下:

优点:客户端不再关心产品创建的所有细节工作,需要哪个对象直接向工厂提需求即可。这样做到了职责分离。

缺点:对于某一个类型下的所有产品都是由工厂生产的,万一这个工厂类出点问题,怎么办?万一后面系统要扩展了,我们不得倒过去修改工厂类,这不符合OCP开闭原则啊!

工厂方法模式

工厂方法模式是对简单工厂模式的一种优化,它在工厂角色上再多了一个抽象工厂角色,所以它的角色分为如下一些:

抽象工厂角色、具体工厂角色、抽象产品角色、具体产品角色

我们通过代码来看一看

抽象产品

/**
 * 抽象产品角色
 */
public abstract class Weapon {
    public abstract void attack();
}

具体产品

/**
 * 具体产品角色
 */
public class Gun extends Weapon {
    @Override
    public void attack() {
        System.out.println("开枪射击~~");
    }
}

/**
 * 具体产品角色
 */
public class Fighter extends Weapon {
    @Override
    public void attack() {
        System.out.println("战斗机攻击~~");
    }
}

抽象工厂角色

/**
 * 抽象工厂角色
 */
public interface WeaponFactory {
    Weapon get();
}

具体工厂角色

/**
 * 具体工厂角色
 */
public class GunFactory implements WeaponFactory {
    @Override
    public Weapon get() {
        return new Gun();
    }
}

/**
 * 具体工厂角色
 */
public class FighterFactory implements WeaponFactory {
    @Override
    public Weapon get() {
        return new Fighter();
    }
}

最终客户端需要哪个产品直接找对应的工厂索要即可

public class Client {
    public static void main(String[] args) {
        WeaponFactory factory = new GunFactory();
        Weapon gun = factory.get();
        gun.attack();

        WeaponFactory factory1 = new FighterFactory();
        Weapon fighter = factory1.get();
        fighter.attack();
    }
}

这个时候我们可以看到当我们想要扩展一个新的产品时,不会动到现有结构,我们只需要新增一个具体产品类,同时再新增一个对应的具体工厂即可。

工厂方法模式的又有哪些优缺点呢?

优点:扩展性高

缺点:每增加一个产口就需要增加一个具体类的对象实现工厂,类的数量增长过快,在一定程度上增加了系统的复杂度。

抽象工厂模式

抽象工厂模式相对于工厂方法模式做了一个折中的处理,工厂方法模式是一个产品对一个工厂类,而抽象工厂模式是多个产品对应一个工厂类。

抽象工厂模式会把产品进行分类,每一类产生提供一个具体的生产工厂

抽象工厂模工中有如下四个角色

抽象工厂角色、具体工厂角色、抽象产品角色、具体产品角色

抽象产品

/**
 * 抽象产品族 - 武器
 */
public abstract class Weapon {
    public abstract void attack();
}


/**
 * 抽象产品族 - 水果
 */
public abstract class Fruit {
    /**
     * 水果的甜度
     */
    public abstract void sweetness();
}

具体产品

/**
 * 武器产品 - Gun
 */
public class Gun extends Weapon {
    @Override
    public void attack() {
        System.out.println("开枪射击~~");
    }
}

/**
 * 武器产品 - Dagger
 */
public class Dagger extends Weapon {
    @Override
    public void attack() {
        System.out.println("匕首砍~~~");
    }
}


/**
* 水果产品 - Grape
*/
public class Grape extends Fruit {
    @Override
    public void sweetness() {
        System.out.println("草莓甜度 - 高");
    }
}


/**
* 水果产品 - Blueberry
*/
public class Blueberry extends Fruit {
    @Override
    public void sweetness() {
        System.out.println("葡萄甜度 - 中");
    }
}

抽象工厂

/**
 * 抽象工厂类
 */
public abstract class AbstractFactory {
    public abstract Fruit getFruit(String fruitType);
    public abstract Weapon getWeapon(String weaponType);
}

具体工厂

/**
 * 具体工厂类 - 武器
 */
public class WeaponFactory extends AbstractFactory {
    @Override
    public Fruit getFruit(String fruitType) {
        return null;
    }

    @Override
    public Weapon getWeapon(String weaponType) {
        if(weaponType == null || weaponType.isEmpty()) {
            throw new RuntimeException("请提供具体要生产的武器~~");
        }
        return switch(weaponType) {
            case "Gun" -> new Gun();
            case "Dagger" -> new Dagger();
            default -> throw new RuntimeException("无法产生该武器~~");
        };
    }
}


/**
 * 具体工厂类 - 水果
 */
public class FruitFactory extends AbstractFactory {
    @Override
    public Fruit getFruit(String fruitType) {
        if(fruitType == null || fruitType.isEmpty()) {
            throw new RuntimeException("请提供具体要生产的水果~~");
        }
        return switch(fruitType){
            case "grape" -> new Grape();
            case "blueberry" -> new Blueberry();
            default -> throw new RuntimeException("不支持的水果类型");
        };
    }

    @Override
    public Weapon getWeapon(String weaponType) {
        return null;
    }
}

客户端在使用时可以如下:

// 测试程序
public class Client {
    public static void main(String[] args) {
        AbstractFactory factory = new FruitFactory();
        Fruit blueberry = factory.getFruit("blueberry");
        blueberry.sweetness();
        Fruit grape = factory.getFruit("grape");
        grape.sweetness();
        System.out.println("=======================================");
        factory = new WeaponFactory();
      

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/919423.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【机器学习】机器学习中用到的高等数学知识-7.信息论 (Information Theory)

熵 (Entropy):用于评估信息的随机性,常用于决策树和聚类算法。交叉熵 (Cross-Entropy):用于衡量两个概率分布之间的差异,在分类问题中常用。 信息论作为处理信息量和信息传输的数学理论,在机器学习中具有广泛的应用。…

高亮变色显示文本中的关键字

效果 第一步:按如下所示代码创建一个用来高亮显示文本的工具类: public class KeywordUtil {/*** 单个关键字高亮变色* param color 变化的色值* param text 文字* param keyword 文字中的关键字* return*/public static SpannableString highLigh…

【图像处理识别】数据集合集!

本文将为您介绍经典、热门的数据集,希望对您在选择适合的数据集时有所帮助。 1 CNN-ImageProc-Robotics 机器人 更新时间:2024-07-29 访问地址: GitHub 描述: 通过 CNN 和图像处理进行机器人对象识别项目侧重于集成最先进的深度学习技术和…

VTK知识学习(10)- 渲染引擎

1、前言 vtkProp; vtkAbstractMapper; vtkProperty; vtkCamera; vtkLight; vtkRenderer; vtkRenderWindow; vtkRenderWindowInteractor; vtkTransform; vtkLookupTable;………… 这些类都是与数据显示或渲染相关的。 用计算机图形学的专业词汇来说,就是它…

网络基础(3)https和加密

http其它的报头 直接看图片: 上图中的第一个和第二个类型之前已经使用过了也就不多做说明了,第三个报头类型使用的很少了。第四个报头类型主要就使用在一些灰度更新的应用上,确定用户使用的软件的版本不让其访问该版本不能访问的功能。下一个…

高阶C语言之五:(数据)文件

目录 文件名 文件类型 文件指针 文件的打开和关闭 文件打开模式 文件操作函数(顺序) 0、“流” 1、字符输出函数fputc 2、字符输入函数fgetc 3、字符串输出函数fputs 4、 字符串输入函数fgets 5、格式化输入函数fscanf 6、格式化输出函数fpr…

C#获取视频第一帧_腾讯云媒体处理获取视频第一帧

一、 使用步骤: 第一步、腾讯云开启万象 第二步、安装Tencent.QCloud.Cos.Sdk 包 第三步、修改 腾讯云配置 图片存储目录配置 第四步、执行获取图片并保存 二、封装代码 using System.Text; using System.Threading.Tasks;using COSXML.Model.CI; using COSXML.A…

分词器的概念(通俗易懂版)

什么是分词器?简单点说就是将字符序列转化为数字序列,对应模型的输入。 通常情况下,Tokenizer有三种粒度:word/char/subword word: 按照词进行分词,如: Today is sunday. 则根据空格或标点进行分割[today, is, sunda…

Jenkins更换主题颜色+登录页面LOGO图片

默认主题和logo图片展示 默认主题黑色和白色。 默认LOGO图片 安装插件 Login ThemeMaterial Theme 系统管理–>插件管理–>Available plugins 搜不到Login Theme是因为我提前装好了 没有外网的可以参考这篇离线安装插件 验证插件并修改主题颜色 系统管理–>A…

11.19.2024刷华为OD

文章目录 HJ51HJ53 杨辉三角HJ56HJ57 高精度整数加法HJ58HJ60 简单题HJ63 DNA序列(简单题)语法知识记录 HJ51 https://www.nowcoder.com/practice/54404a78aec1435a81150f15f899417d?tpId37&tags&title&difficulty0&judgeStatus0&…

C语言零基础入门

一、输入输出 &#xff08;1&#xff09;scanf scanf 是C语言中的一个标准库函数&#xff0c;用于从标准输入&#xff08;通常是键盘&#xff09;读取数据。scanf 函数定义在 <stdio.h> 头文件中。 #include <stdio.h>int main(void) {//读取整数 int num;print…

应聘美容师要注意什么?博弈美业收银系统/管理系统/拓客系统分享建议

随着美容行业的不断发展&#xff0c;成为一名优秀的美容师需要具备一系列重要的技能和品质。无论是在面试过程中还是在实际工作中&#xff0c;以下建议将帮助你在应聘美容师职位时脱颖而出&#xff1a; ▶ 专业技能和资格 首先&#xff0c;确保你具备所需的专业技能和资格。这…

JVM性能分析工具JProfiler的使用

一、基本概念 JProfiler&#xff1a;即“Java Profiler”&#xff0c;即“Java分析器”或“Java性能分析工具”。它是一款用于Java应用程序的性能分析和调试工具&#xff0c;主要帮助开发人员识别和解决性能瓶颈问题。 JVM&#xff1a;即“Java Virtual Machine”&#xff0c…

css鼠标移动效果高亮追随效果

如图所示&#xff0c;鼠标移动有一块高亮随着鼠标移动。代码如下&#xff1a;(vue3篇) <div class"container"><span class"use-hover-hglh-element trail" :style"isShow ? dyStyle : { opacity: 0 }"></span></div>…

PHP屏蔽海外IP的访问页面(源代码实例)

PHP屏蔽海外IP的访问页面&#xff08;源代码实例&#xff09;&#xff0c;页面禁用境外IP地址访问 <?php/*** 屏蔽海外ip访问* 使用ip2long函数得到ip转为整数的值&#xff0c;判断值是否在任一一个区间中* 以下是所有国内ip段* 调用方法&#xff1a;IschinaIp($ALLIPS)* …

现代分布式系统新法宝:基于单元的架构

- 前言 - 数十年来&#xff0c;IT 业界一直在努力掌握分布式系统。然而&#xff0c;随着系统日益复杂&#xff0c;给开发数字产品的组织带来巨大挑战。可以说&#xff0c;分布式系统最棘手的方面之一是面对故障时的可靠性&#xff0c;特别是现代分布式系统使用大量物理与虚拟资…

2.8 群辉 黑群晖 意味断电 抱歉,您所指定的页面不存在。

实验室组装的黑群晖施工时不小心被意味断电&#xff0c;然后出现了如下图&#xff1a; 对于7.1.1的系统来说&#xff0c;这个是由于libsynopkg.so.1和libsynoshare.so.7这两个文件出问题所致。 因此&#xff0c;解决方法也比较简单就是把好的文件恢复到/lib文件夹下即可。 这…

【视频讲解】Python深度神经网络DNNs-K-Means(K-均值)聚类方法在MNIST等数据可视化对比分析...

全文链接&#xff1a;https://tecdat.cn/?p38289 分析师&#xff1a;Cucu Sun 近年来&#xff0c;由于诸如自动编码器等深度神经网络&#xff08;DNN&#xff09;的高表示能力&#xff0c;深度聚类方法发展迅速。其核心思想是表示学习和聚类可以相互促进&#xff1a;好的表示会…

K8S资源限制之ResourceQuota

ResourceQuota介绍 在K8S中&#xff0c;大部分资源都可以指定到一个名称空间下&#xff0c;因此可以对一个名称空间的计算资源&#xff0c;存储资源&#xff0c;资源数量等维度做资源限制。 如限制pod数量、svc数量&#xff0c;控制器数量&#xff0c;限制PVC请求的存储量 注…

【Android原生问题分析】夸克、抖音划动无响应问题【Android14】

1 问题描述 偶现问题&#xff0c;用户打开夸克、抖音后&#xff0c;在界面上划动无响应&#xff0c;但是没有ANR。回到Launcher后再次打开夸克/抖音&#xff0c;发现App的界面发生了变化&#xff0c;但是仍然是划不动的。 2 log初分析 复现问题附近的log为&#xff1a; 用户…