当前位置: 首页 > news >正文

Spring的设计模式----工厂模式及对象代理

一、工厂模式       

 工厂模式提供了一种将对象的实例化过程封装在工厂类中的方式。通过使用工厂模式,可以将对象的创建与使用代码分离,提供一种统一的接口来创建不同类型的对象。定义一个创建对象的接口让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

工厂模式:
抽象产品(Abstract Product):定义了产品的共同接口或抽象类。它可以是具体产品类的父类或接口,规定了产品对象的共同方法。
具体产品(Concrete Product):实现了抽象产品接口,定义了具体产品的特定行为和属性。
抽象工厂(Abstract Factory):声明了创建产品的抽象方法,可以是接口或抽象类。它可以有多个方法用于创建不同类型的产品。
具体工厂(Concrete Factory):实现了抽象工厂接口,负责实际创建具体产品的对象。

实现创建一个 INoodles接口和实现 INoodles 接口的实体类。下一步是定义工厂类 INoodlesFactory。

public class NoodleFactory {/*** 规范下面条类型* */public static final int NOODLE_YOUPO = 1;public static final int NOODLE_REGAN = 2;public static final int NOODLE_LANZHOULA = 3;/***创建面条**/public static  INoodles getNoodle(int type){if (type == 1){return new YouPoMianNoodleImp();}else if(type ==2){return new ReGanMianNoodleImp();}else if(type ==3 ){return new LanZhouLaMianImp();}return null;}}

 

总结

工厂模式通过将对象的创建与使用分离,提供了更好的灵活性和可维护性。选择合适的工厂模式可以根据具体的需求和场景来决定。

二、代理模式 

什么是代理模式?

代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。通俗的来讲代理模式就是我们生活中常见的中介。     举个例子来说明:假如说我现在想买一辆二手车,虽然我可以自己去找车源,做质量检测等一系列的车辆过户流程,但是这确实太浪费我得时间和精力了。我只是想买一辆车而已为什么我还要额外做这么多事呢?于是我就通过中介自己喜欢的车,然后付钱就可以了。

为什么要用代理模式?

1.中介隔离作用:    

 在某些情况下,一个客户类不想或者不能直接引用一个委托对象,而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口。

2.开闭原则,增加功能: 代理类除了是客户类和委托类的中介之外,我们还可以通过给代理类增加额外的功能来扩展委托类的功能,这样做我们只需要修改代理类而不需要再修改委托类,符合代码设计的开闭原则。

有哪几种代理模式? 我们有多种不同的方式来实现代理。如果按照代理创建的时期来进行分类的话 可以分为两种:

静态代理:         静态代理是由程序员创建或特定工具自动生成源代码,在对其编译。          在程序员运行之前,代理类.class文件就已经被创建了。

动态代理和静态代理是面向对象编程中的两种代理模式,它们的主要区别在于代理对象的创建方式以及使用场景。

静态代理

  • 定义:静态代理是指在程序编译时就已经确定了代理类的实现。开发人员需要手动编写代理类,并将目标对象的功能进行封装。

  • 优点

    • 代理类可以针对某一个接口实现具体的业务逻辑。
    • 在编译时就能检查到错误。
  • 缺点

    • 每个需要代理的类都需要创建一个代理类,增加了代码量和维护成本。
    • 不适应于需要灵活修改代理逻辑的场合。

*      动态代理:
*              动态代理是在程序运行时通过反射机制动态创建的。
*              动态代理分为:
*                  基于接口的动态代理(jdk自带)
*                  基于子类的动态代理(第三方)

动态代理

  • 定义:动态代理是在运行时根据指定的接口生成代理对象,不需要提前创建代理类。它通常使用 Java 的反射机制或其他框架(如 AOP)来实现。

  • 优点

    • 可以为多个类生成代理,不需要手动创建大量的代理类。
    • 灵活性高,可以在运行时决定代理的行为。
  • 缺点

    • 运行时生成可能会引入性能开销。
    • 难以进行编译时检查。

1.基于接口的动态代理(jdk自带)

原理

JDK 自带的动态代理只能代理实现了接口的类。通过 java.lang.reflect.Proxy 类和 InvocationHandler 接口来实现。

2.基于子类的动态代理(第三方)

原理:

CGLIB(Code Generation Library)是一个强大的、高性能的代码生成库,它通过继承来实现代理。与 JDK 基于接口的动态代理不同,CGLIB 可以直接对类进行代理,只要所代理的类没有被声明为 final

代码结构和说明

  1. 被代理对象:通过IAccountService toProxyService指定了一个接口,该接口的实现会被代理。

  2. 事务工具类TransactionUtil transactionUtil用于处理事务的开始、提交和回滚。

  3. 创建代理的createProxy方法:这个方法使用Java反射API创建一个代理对象,并在调用实际服务方法前后处理事务。

总结

  • 基于接口的动态代理(JDK 自带)

    • 只支持接口。
    • 使用简单,适合轻量级的场景。
  • 基于子类的动态代理(CGLIB)

    • 可以代理普通类(不必实现接口)。
    • 需要引入第三方库,适合复杂的业务逻辑。

在实际开发中,可以根据需求选择适合的动态代理方式。对于接口较多的场景,建议使用 JDK 自带的动态代理;而需要直接代理类时,则可以使用 CGLIB。

案例

public class ProxyBeanFactory {//1.被代理对象IAccountService toProxyService;public void setToProxyService(IAccountService toProxyService) {this.toProxyService = toProxyService;}//装配事务工具类TransactionUtil transactionUtil;public void setTransactionUtil(TransactionUtil transactionUtil) {this.transactionUtil = transactionUtil;}//2.创建代理public IAccountService createProxy(){IAccountService proxy = (IAccountService) Proxy.newProxyInstance(toProxyService.getClass().getClassLoader(), toProxyService.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object o = null;try {transactionUtil.beginTx();o = method.invoke(toProxyService,args);transactionUtil.commitTx();} catch (Exception e) {e.printStackTrace();transactionUtil.rollbackTx();} finally {transactionUtil.closeTx();}return o;}});return proxy;}
}
 <!-- 事务工具类 --><bean id="transactionUtil" class="com.xn.util.TransactionUtil"><property name="connectionUtil" ref="connectionUtil"/></bean>该bean负责管理事务,确保在数据库操作中能够正确处理事务的开始、提交和回滚。<!-- 注入dao --><bean id="mapperImp" class="com.xn.dao.AccountMapperImp"><property name="queryRunner" ref="queryRunner"/><property name="connectionUtil" ref="connectionUtil"/></bean>AccountMapperImp类负责与数据库交互,确保queryRunner和connectionUtil的正确配置以执行数据库操作。<!-- 注入被代理service --><bean id="service" class="com.xn.service.AccountServiceImp"><property name="mapper" ref="mapperImp"/></bean><!-- 注入代理service --><bean id="proxyService" class="com.xn.service.AccountServiceImp" factory-bean="factory" factory-method="createProxy"/><bean id="factory" class="com.xn.factory.ProxyBeanFactory"><property name="transactionUtil" ref="transactionUtil"/><property name="toProxyService" ref="service"/></bean>通过ProxyBeanFactory创建的proxyService用于在调用服务时添加额外的功能(如事务管理)。确保代理逻辑的实现能够正确处理服务调用。<!-- 注入controller --><bean id="controller" class="com.xn.controller.AccountControllerImp"><property name="service" ref="proxyService"/></bean>AccountControllerImp类负责处理用户请求,并将请求委托给proxyService进行业务处理。

JAVA六大设计原则 

Java的六大设计原则(SOLID原则)是面向对象设计的重要指导方针,这些原则帮助开发者编写可维护、可扩展和易于理解的代码。具体包括:

  1. 单一责任原则(Single Responsibility Principle)

    • 一个类应该只有一个原因引起变化,即一个类只应该负责一项功能。这样可以提高模块化程度,降低类之间的耦合度。
  2. 开放-关闭原则(Open/Closed Principle)

    • 软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。也就是说,在不修改现有代码的情况下,可以增加新功能,通过扩展现有的类或接口来实现。
  3. 里氏替换原则(Liskov Substitution Principle)

    • 子类对象应该能够替换父类对象,并且程序的行为不会发生变化。即实现继承时,子类应能无缝替换父类,保持程序的正确性。
  4. 接口隔离原则(Interface Segregation Principle)

    • 不应该强迫一个类依赖于它不需要的接口。许多特定的接口比一个通用接口更好,即应尽量使用多个小接口,避免接口的臃肿。
  5. 依赖倒置原则(Dependency Inversion Principle)

    • 高层模块不应依赖于低层模块,二者都应依赖于抽象(接口或抽象类);而且抽象不应依赖于细节,细节应依赖于抽象。这样可以减少模块之间的耦合度。
  6. 最少知识原则(Law of Demeter)(有时也包括在SOLID原则中,但不严格归入):

    • 一个对象应该对其他对象有尽可能少的了解。也就是说,一个对象应该只与直接的朋友(协作对象)交互,而不与其他对象进行复杂的交互。

这些原则的作用

  • 提高代码的可读性和可维护性:遵循这些原则,代码结构更加清晰易懂,维护的时候可以减少对其他模块的影响。
  • 降低耦合度,提高内聚性:这些原则鼓励模块之间的松散耦合,增强了模块的独立性。
  • 促进代码复用:良好的设计使得代码更容易在不同的项目中复用。
  • 增强测试性:代码更容易被单元测试,提高了单元测试的可行性。

JAVA23种设计模式

在软件工程当中,设计原则和设计模式是不同的.

设计原则

设计原则是为了更好的设计软件的高层指导方针. 

它不提供具体的实现方式也不会绑定任何一种编程语言.  

最常用的原则是SOLID(SRP, OCP, LSP, ISP, DIP)原则

设计模式

设计模式对关于面向对象问题的具体解决方案.

比如说,如果你想创建一个类而且它在任何时刻只会有一个对象,那么你就应该使用单例类模式.

设计模式是经过大量检测的安全的做法.

“饿汉式”和“懒汉式”是单例模式的两种实现方式。它们在实例化对象的时机和方式上存在明显的区别。下面分别介绍这两种方式。

1. 饿汉式

特点:
  • 实例在类加载时就被创建,所以线程安全。
  • 不支持延迟加载,因为实例一旦创建就存在,占用资源。
  • 实现简单,代码少。
/*** 饿汉式* */
public class Student {//3.创建static修饰的成员变量private static Student stu = new Student();//1.设计私有构造方法private Student(){super();}//2.提供共有的方法public static synchronized Student getInstance(){return stu;}}//true

2. 懒汉式

特点:
  • 实例在第一次调用时才被创建,支持延迟加载。
  • 需要考虑线程安全问题。
  • 代码稍微复杂,因为需要进行同步处理。
实现:

有多种方式实现懒汉式,以下是其中两种常见的实现。

 线程安全的懒汉式(使用 synchronized)
/*** 懒汉式* */
public class Student {//3.创建static修饰的成员变量private static Student stu;//1.设计私有构造方法private Student(){super();}//2.提供共有的方法public static synchronized Student getInstance(){if(stu == null){stu = new Student();}return stu;}}//true

总结

  • 饿汉式

    • 实例在类加载时创建,线程安全。
    • 一旦加载即占用资源,不支持延迟加载。
  • 懒汉式

    • 实例在第一次调用时创建,支持延迟加载。
    • 需要处理线程安全问题,代码相对复杂。

选择使用哪种方式一般依据具体的业务需求、性能考虑和资源管理来定。在一些早期的项目中,懒汉式较受欢迎,而在现代的多线程环境中,饿汉式因其简单和线程安全的特性也常被使用。

3、普通

相关文章:

Spring的设计模式----工厂模式及对象代理

一、工厂模式 工厂模式提供了一种将对象的实例化过程封装在工厂类中的方式。通过使用工厂模式&#xff0c;可以将对象的创建与使用代码分离&#xff0c;提供一种统一的接口来创建不同类型的对象。定义一个创建对象的接口让其子类自己决定实例化哪一个工厂类&#xff0c;…...

【算法】浅析广度优先搜索算法

广度优先搜索算法&#xff1a;层层推进&#xff0c;全面探索 1. 引言 在计算机科学和算法设计中&#xff0c;广度优先搜索&#xff08;Breadth-First Search&#xff0c;简称BFS&#xff09;是一种用于遍历或搜索树或图的算法。这种算法从起点开始&#xff0c;优先访问所有距…...

分布式时序数据库TimeLyre 9.2发布:原生多模态、高性能计算、极速时序回放分析

在当今数据驱动的世界中&#xff0c;多模态数据已经成为企业的重要资产。随着数据规模和多样性的不断增加&#xff0c;企业不仅需要高效存储和处理这些数据&#xff0c;更需要从中提取有价值的洞察。工业领域在处理海量设备时序数据的同时&#xff0c;还需要联动分析警报信息、…...

PMP考试题库每日五题+答案解析

第1题&#xff08;单选题&#xff09;某技术开发项目正在开展&#xff0c;目前项目所用成本还在预算范围内&#xff0c;但是已经落后项目进度计划三周。项目集经理在最近的项目状态报告中了解到这一项目信息&#xff0c;他要求项目经理必须在计划的交付日期之前完成可交付成果。…...

机器学习用python还是R,哪个更好?

目录 1. 语言特点 1.1 Python的语言特点 1.2 R的语言特点 2. 库支持 2.1 Python的库支持 2.2 R的库支持 3. 性能 3.1 Python的性能 3.2 R的性能 4. 社区支持 4.1 Python的社区支持 4.2 R的社区支持 5. 学习曲线 5.1 Python的学习曲线 5.2 R的学习曲线 6. 实际应…...

【数据结构】mapset详解

&#x1f341;1. Set系列集合 Set接口是一种不包含重复元素的集合。它继承自Collection接口&#xff0c;所以可以使用Collection所拥有的方法&#xff0c;Set接口的实现类主要有HashSet、LinkedHashSet、TreeSet等&#xff0c;它们各自以不同的方式存储元素&#xff0c;但都遵…...

数据结构(邓俊辉)学习笔记】词典 02—— 散列函数

文章目录 1. 冲突难免2. 何为优劣3. 整除留余4. 以禅为师5. M A D6. 平方取中7. 折叠汇总8. 伪随机数9. 多项式10. Vorldmort 1. 冲突难免 好&#xff0c;接下来的这一节我们就来介绍散列策略中的第一项&#xff0c;也是最重要的技术&#xff0c;散列函数的设计与定制。 在上…...

Python学习(1):使用Python的Dask库实现并行计算

目录 一、Dask介绍 二、使用说明 安装 三、测试 1、单个文件中实现功能 2、运行多个可执行文件 最近在写并行计算相关部分&#xff0c;用到了python的Dask库。 Dask官网&#xff1a;Dask | Scale the Python tools you love 一、Dask介绍 Dask是一个灵活的并行和分布式…...

数据结构 - 哈希表

文章目录 前言一、哈希思想二、哈希表概念三、哈希函数1、哈希函数设计原则2、常用的哈希函数 四、哈希冲突1、什么是哈希冲突2、解决哈希冲突闭散列开散列 五、哈希表的性能分析时间复杂度分析空间复杂度分析 前言 一、哈希思想 哈希思想&#xff08;Hashing&#xff09;是计…...

电商选品这几点没做好,等于放弃80%的流量!

在竞争激烈的电商领域&#xff0c;选品是决定店铺命运的核心环节。到底是哪些关键要点能够帮助我们在选品时抢占流量高地&#xff0c;稳步出单呢&#xff1f; 一、深入了解市场需求 选品的第一步是对市场进行深入调研。要关注当前的消费趋势、热门品类以及潜在的需求缺口。通…...

【教程】最新可用!Docker国内镜像源列表

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 目录 镜像加速器地址 用法示例 一、自动配置地址 二、配置单次地址 镜像加速器地址 Docker镜像加速站https://hub.uuuadc.top/docker.1panel.live…...

使用RabbitMQ在Spring Boot入门实现简单的消息的发送与接收

文章目录 要引入spring-boot-starter-amqp依赖才能开始后续操作 1. 配置RabbitMQ地址2. 编写消息发送测试类3. 实现消息接收 在本文中&#xff0c;我们将介绍如何在Spring Boot应用中使用RabbitMQ实现消息的发送与接收。我们将创建两个服务&#xff0c;一个用于发送消息&#x…...

基于物联网的水质监测系统设计与实现:React前端、Node.js后端与TCP/IP协议的云平台集成(代码示例)

一、项目概述 随着环境保护意识的增强&#xff0c;水质监测在水资源管理和污染防治中变得尤为重要。本项目旨在设计一个基于物联网的水质监测系统&#xff0c;能够实时监测水中的pH值、溶解氧、电导率和浊度等参数&#xff0c;并将数据传输至云端&#xff0c;以便进行分析和可…...

Vcpkg安装指定版本包或自定义安装包

在使用 vcpkg 安装特定版本的包或自定义包时&#xff0c;你可以按照以下步骤进行操作&#xff1a; 安装特定版本的包 列出可用的版本&#xff1a; 使用以下命令列出特定包的所有可用版本&#xff1a; vcpkg search <package-name>安装特定版本&#xff1a; 使用 vcpkg …...

【C++深度探索】红黑树实现Set与Map的封装

&#x1f525; 个人主页&#xff1a;大耳朵土土垚 &#x1f525; 所属专栏&#xff1a;C从入门至进阶 这里将会不定期更新有关C/C的内容&#xff0c;欢迎大家点赞&#xff0c;收藏&#xff0c;评论&#x1f973;&#x1f973;&#x1f389;&#x1f389;&#x1f389; 文章目录…...

终于有人把客户成功讲明白了

作者&#xff1a;沈建明 对ToB企业来说&#xff0c;只有客户成功才能带来持久增长&#xff0c;在SaaS企业下行大背景下&#xff0c;客户成功是唯一的救命稻草。大家是不是都听过这样的说法&#xff1f; ToB和SaaS企业的老客户贡献对于企业至关重要。因为获取新客户的成本是留…...

[新械专栏] 肾动脉射频消融仪及一次性使用网状肾动脉射频消融导管获批上市

近日&#xff0c;国家药品监督管理局批准了上海魅丽纬叶医疗科技有限公司“肾动脉射频消融仪”和“一次性使用网状肾动脉射频消融导管”两个创新产品注册申请。 肾动脉射频消融仪由主机、脚踏开关、主机连接线、中性电极连接线以及电源线组成。一次性使用网状肾动脉射频消融导…...

leetcode-119-杨辉三角II

原理&#xff1a; 1、初始化每行一维数组nums[1]&#xff1b; 2、从第2行开始&#xff0c;在nums的头插入0&#xff08;因为杨辉三角每行的第一个1相当于是上一行的1与其前面的0相加之和&#xff09;后进行相加操作。 代码&#xff1a;...

【第八节】python正则表达式

目录 一、python中的re模块 1.1 基本匹配和搜索 1.2 替换和分割 1.3 编译正则表达式 二、正则表达式对象 2.1 re.RegexObject 和 re.MatchObject 2.2 正则表达式修饰符 - 可选标志 2.3 正则表达式模式 2.4 正则表达式实例 一、python中的re模块 正则表达式是一种独特的…...

三大浏览器Google Chrome、Edge、Firefox内存占用对比

问题 Chrome、Edg、Firefox三家究竟谁的占用少 结论 打开一个页面内存占用 Firefox>Edge>Chrome 打开打量页面内存占用 Firefox>Chrome>Edge 从监视器可以看到Edge增加一个页面增加一个页面不到100M而其它浏览器需要150M左右;Firefox浏览器主线程内存占用800M比…...

SQLSERVER-DB操作记录

在SQL Server中&#xff0c;将查询结果放入一张新表可以通过几种方法实现。 方法1&#xff1a;使用SELECT INTO语句 SELECT INTO 语句可以直接将查询结果作为一个新表创建出来。这个新表的结构&#xff08;包括列名和数据类型&#xff09;将与查询结果匹配。 SELECT * INTO 新…...

HTMLCSS 学习总结

目录 ​​​一、HTML核心概念​​ ​​三大前端技术作用​​ ​​HTML基础结构​​ 开发工具&#xff1a;VS Code 专业配置​​​​安装步骤​​&#xff1a; ​​二、HTML标签大全&#xff08;含表格&#xff09;​​ ​​三、CSS核心技术​​ 1. 三种引入方式对比 2.…...

在 Vue 的template中使用 Pug 的完整教程

在 Vue 的template中使用 Pug 的完整教程 引言 什么是 Pug&#xff1f; Pug&#xff08;原名 Jade&#xff09;是一种高效的网页模板引擎&#xff0c;通过缩进式语法和简洁的写法减少 HTML 的冗长代码。Pug 省略了尖括号和闭合标签&#xff0c;使用缩进定义结构&#xff0c;…...

四、Sqoop 导入表数据子集

作者&#xff1a;IvanCodes 日期&#xff1a;2025年6月4日 专栏&#xff1a;Sqoop教程 当不需要将关系型数据库中的整个表一次性导入&#xff0c;而是只需要表中的一部分数据时&#xff0c;Sqoop 提供了多种方式来实现数据子集的导入。这通常通过过滤条件或选择特定列来完成。 …...

Git 使用大全:从入门到精通

Git 是目前最流行的分布式版本控制系统&#xff0c;被广泛应用于软件开发中。本文将全面介绍 Git 的各种功能和使用方法&#xff0c;包含大量代码示例和实践建议。 文章目录 Git 基础概念版本控制系统Git 的特点Git 的三个区域Git 文件状态 Git 安装与配置安装 GitLinuxmacOSWi…...

AcWing 3417:砝码称重——位集合

【题目来源】 3417. 砝码称重 - AcWing题库 【题目描述】 你有一架天平和 N 个砝码&#xff0c;这 N 个砝码重量依次是 W1,W2,⋅⋅⋅,WN。 请你计算一共可以称出多少种不同的正整数重量&#xff1f; 注意砝码可以放在天平两边。 【输入格式】 输入的第一行包含一个整数 N。 …...

Flask与Celery 项目应用(shared_task使用)

目录 1. 项目概述主要功能技术栈 2. 项目结构3. 环境设置创建虚拟环境并安装依赖主要依赖 4. 应用配置Flask应用初始化 (__init__.py)Celery应用初始化 (make_celery.py) 5. 定义Celery任务 (tasks.py)任务说明 6. 创建API端点 (views.py)API端点说明 7. 前端界面 (index.html)…...

typeof运算符 +unll和undefined的区别

typeof运算符 JavaScript 有三种方法&#xff0c;可以确定一个值到底是什么类型。而我们 现在需要接触到的就是typeof 数值返回number 1 typeof 123 // "number" 字符串返回string 1 typeof 123 // "string" 布尔值返回boolean 1 typeof fal…...

【笔记】PyCharm 使用问题反馈与官方进展速览

#工作记录 https://youtrack.jetbrains.com/issue/IJPL-190308 【笔记】记一次PyCharm的问题反馈_the polyglot context is using an implementation th-CSDN博客 【笔记】与PyCharm官方沟通解决开发环境问题-CSDN博客 与 JetBrains 官方沟通记录&#xff08;PyCharm 相关问题…...

跟进一下目前最新的大数据技术

搭建最新平台 40C64G服务器&#xff0c;搭建3节点kvm&#xff0c;8C12G。 apache-hive-4.0.1-bin apache-tez-0.10.4-bin flink-1.20.1 hadoop-3.4.1 hbase-2.6.2 jdk-11.0.276 jdk8u452-b09 jdk8终于可以不用了 spark-3.5.5-bin-hadoop3 zookeeper-3.9.3 trino…...