你不能不了解的Java23中设计模式之【抽象工厂模式】

news/2024/11/19 13:44:05/

目录

一.介绍抽象工厂模式

1.概念

2.结构: 抽象工厂模式包含以下角色:

3.工作原理:

4.应用场景: 抽象工厂模式适用于以下情况:

5.使用方法:

二.具体实例通过抽象工厂模式实现计算器

1.创建Maven工程(按照小编这样操作即可)

2.导入依赖(pom.xml)

3.构建一个接口(含一个用于进行计算的方法 calculate。该方法接受两个参数, 即 firstNumber 和 secondNumber,并返回一个 double 类型的结果。)

 4.定义具的 Addition, Subtraction, Multiplication 和 Division 分别实现(加减乘除):

4.1加法

4.2减法

4.3乘法

4.4除法

5.创建一个用于生成计算器实例的抽象工厂 CalculatorFactory

6.创建具体的工厂类 AdditionFactory, SubtractionFactory, MultiplicationFactory 和 DivisionFactory 来生产相应的计算器实例

6.1加法工厂

6.2减法工厂

6.3乘法工厂

6.4除法工厂

7.创建一个 CalculatorApp 类,它将使用 CalculatorFactory 来生成所需类型的 Calculator 实例

8.展示效果图


前言:

象工厂模式是一种创建型设计模式,它提供了一种方法来创建一组相关或相互依赖的对象,而无需指定具体的类。通过使用抽象工厂模式,我们可以将对象的创建与使用分离,从而使代码更加灵活、可扩展和可维护。

在本博客中,我们将介绍抽象工厂模式的概念、结构和工作原理,以及在实际开发中的应用场景和使用方法。

首先,我们将详细解释什么是工厂模式,以及为什么需要使用抽象工厂模式。我们将探讨其与其他创建型设计模式的区别,并提供一些示例来说明其优势和适用性。

接下来,我们将介绍抽象工厂模式的核心组件,包括抽象工厂接口、具体工厂类和抽象产品接口。我们将详细说明它们各自的职责和关系,并通过代码示例来说明如何实现这些组件。

然后,我们将探讨抽象工厂模式的工作原理。我们将解释如何通过工厂方法来创建产品对象,并且说明如何组合使用多个工厂方法来创建一组相关的产品对象。

最后,我们将介绍抽象工厂模式在实际开发中的应用场景和使用方法。我们将列举一些常见的使用场景,如图形界面库、数据库访问库等,并提供相应的示例代码来说明如何使用抽象工厂模式解决实际问题。

一.介绍抽象工厂模式

1.概念

抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供了一种创建一组相关或相互依赖对象的接口,而无需指定具体的类。

 抽象工厂模式通过引入抽象工厂和具体工厂的层次结构,使得客户端代码仅与抽象工厂交互,而不必关心具体工厂和产品的细节。这样可以实现客户端代码与具体类的解耦,提高代码的灵活性和可维护性。

2.结构: 抽象工厂模式包含以下角色:

  • 抽象工厂(Abstract Factory):定义了创建一组相关产品的方法接口。
  • 具体工厂(Concrete Factory):实现了抽象工厂的方法,负责创建具体产品的对象。
  • 抽象产品(Abstract Product):定义了产品的共同属性和方法接口。
  • 具体产品(Concrete Product):实现了抽象产品的接口,是抽象工厂创建的对象。

3.工作原理:

  1. 定义抽象工厂接口,其中包含一组创建产品的抽象方法。
  2. 创建具体工厂类,实现抽象工厂接口,根据业务逻辑创建具体产品的对象。
  3. 定义抽象产品接口,其中包含产品的共同属性和方法。
  4. 创建具体产品类,实现抽象产品接口,定义具体产品的属性和方法。
  5. 在客户端代码中,通过抽象工厂创建产品对象,并调用产品的方法进行业务处理。

4.应用场景: 抽象工厂模式适用于以下情况:

  • 系统需要独立于其产品的创建、组合和表示。
  • 系统需要一组相关产品对象,并希望统一管理它们的创建过程。
  • 系统需要提供一个产品的类库,而不想暴露具体实现的细节。
  • 系统需要在运行时切换不同产品族的实现。

5.使用方法:

  1. 定义抽象工厂接口,声明一组创建产品的抽象方法。
  2. 创建具体工厂类,实现抽象工厂接口,分别在每个方法中创建具体产品对象。
  3. 定义抽象产品接口,声明产品的共同属性和方法。
  4. 创建具体产品类,实现抽象产品接口,定义具体产品的属性和方法。
  5. 在客户端代码中,通过抽象工厂对象调用创建产品的方法获取产品对象,并进行业务处理。

通过使用抽象工厂模式,可以提高代码的灵活性和可维护性,同时还可以封装产品创建的细节,使得客户端代码与具体类解耦。这种模式常用于框架设计和库开发中,以便为用户提供一组相关的产品对象。

二.具体实例通过抽象工厂模式实现计算器

1.创建Maven工程(按照小编这样操作即可)

2.导入依赖(pom.xml)

<properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><maven.compiler.plugin.version>3.7.0</maven.compiler.plugin.version><!--添加jar包依赖--><!--1.spring 5.0.2.RELEASE相关--><spring.version>5.0.2.RELEASE</spring.version><!--2.mybatis相关--><mybatis.version>3.4.5</mybatis.version><!--mysql--><mysql.version>5.1.44</mysql.version><!--pagehelper分页jar依赖--><pagehelper.version>5.1.2</pagehelper.version><!--mybatis与spring集成jar依赖--><mybatis.spring.version>1.3.1</mybatis.spring.version><!--3.dbcp2连接池相关 druid--><commons.dbcp2.version>2.1.1</commons.dbcp2.version><commons.pool2.version>2.4.3</commons.pool2.version><!--4.log日志相关--><log4j2.version>2.9.1</log4j2.version><log4j2.disruptor.version>3.2.0</log4j2.disruptor.version><slf4j.version>1.7.13</slf4j.version><!--5.其他--><junit.version>4.12</junit.version><servlet.version>4.0.0</servlet.version><lombok.version>1.18.2</lombok.version><mybatis.ehcache.version>1.1.0</mybatis.ehcache.version><ehcache.version>2.10.0</ehcache.version><redis.version>2.9.0</redis.version><redis.spring.version>1.7.1.RELEASE</redis.spring.version><jackson.version>2.9.3</jackson.version><jstl.version>1.2</jstl.version><standard.version>1.1.2</standard.version><tomcat-jsp-api.version>8.0.47</tomcat-jsp-api.version><commons-fileupload.version>1.3.3</commons-fileupload.version><hibernate-validator.version>5.0.2.Final</hibernate-validator.version><shiro.version>1.3.2</shiro.version></properties>
  <dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><dependency><groupId>org.mockito</groupId><artifactId>mockito-all</artifactId><version>2.0.2-beta</version><scope>test</scope></dependency><!--1.spring相关--><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-orm</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>${spring.version}</version></dependency><!--2.mybatis相关--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>${mybatis.version}</version></dependency><!--mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency><!--pagehelper分页插件jar包依赖--><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>${pagehelper.version}</version></dependency><!--mybatis与spring集成jar包依赖--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>${mybatis.spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>${spring.version}</version></dependency><!--mybatis与ehcache整合--><dependency><groupId>org.mybatis.caches</groupId><artifactId>mybatis-ehcache</artifactId><version>${mybatis.ehcache.version}</version></dependency><!--ehcache依赖--><dependency><groupId>net.sf.ehcache</groupId><artifactId>ehcache</artifactId><version>${ehcache.version}</version></dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>${redis.version}</version></dependency><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-redis</artifactId><version>${redis.spring.version}</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>${jackson.version}</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>${jackson.version}</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>${jackson.version}</version></dependency><!--3.dbcp2连接池相关--><dependency><groupId>org.apache.commons</groupId><artifactId>commons-dbcp2</artifactId><version>${commons.dbcp2.version}</version><exclusions><exclusion><artifactId>commons-pool2</artifactId><groupId>org.apache.commons</groupId></exclusion></exclusions></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>${commons.pool2.version}</version></dependency><!--springmvc依赖--><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${spring.version}</version></dependency><!--4.log日志相关依赖--><!-- log4j2日志相关依赖 --><!-- log配置:Log4j2 + Slf4j --><!-- slf4j核心包--><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>${slf4j.version}</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>jcl-over-slf4j</artifactId><version>${slf4j.version}</version><scope>runtime</scope></dependency><!--核心log4j2jar包--><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-api</artifactId><version>${log4j2.version}</version></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>${log4j2.version}</version></dependency><!--用于与slf4j保持桥接--><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-slf4j-impl</artifactId><version>${log4j2.version}</version></dependency><!--web工程需要包含log4j-web,非web工程不需要--><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-web</artifactId><version>${log4j2.version}</version><scope>runtime</scope></dependency><!--需要使用log4j2的AsyncLogger需要包含disruptor--><dependency><groupId>com.lmax</groupId><artifactId>disruptor</artifactId><version>${log4j2.disruptor.version}</version></dependency><!--5.其他--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>${junit.version}</version><!--<scope>test</scope>&lt;!&ndash;&ndash;&gt;--></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>${servlet.version}</version><scope>provided</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version><scope>provided</scope></dependency><dependency><groupId>jstl</groupId><artifactId>jstl</artifactId><version>${jstl.version}</version></dependency><dependency><groupId>taglibs</groupId><artifactId>standard</artifactId><version>${standard.version}</version></dependency><dependency><groupId>org.apache.tomcat</groupId><artifactId>tomcat-jsp-api</artifactId><version>${tomcat-jsp-api.version}</version></dependency><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>${commons-fileupload.version}</version></dependency><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-validator</artifactId><version>${hibernate-validator.version}</version></dependency><!--shiro依赖--><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>${shiro.version}</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-web</artifactId><version>${shiro.version}</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>${shiro.version}</version></dependency></dependencies>

3.构建一个接口(含一个用于进行计算的方法 calculate。该方法接受两个参数, 即 firstNumber 和 secondNumber,并返回一个 double 类型的结果。)

package com.lz.jsq.jk;/*** @author lz* @create 2023-09-11 9:07*//*** 包含一个用于进行计算的方法 calculate。该方法接受两个参数,* 即 firstNumber 和 secondNumber,并返回一个 double 类型的结果。*/
public interface Calculator {double calculate(double firstNumber, double secondNumber);
}

 4.定义具的 AdditionSubtractionMultiplication 和 Division 分别实现(加减乘除):

4.1加法

package com.lz.jsq.jjcc;import com.lz.jsq.jk.Calculator;/*** @author lz* @create 2023-09-11 9:12*/
public class Addition implements Calculator {@Overridepublic double calculate(double firstNumber, double secondNumber) {return firstNumber + secondNumber;}
}

4.2减法

package com.lz.jsq.jjcc;import com.lz.jsq.jk.Calculator;/*** @author lz* @create 2023-09-11 9:14*/
public class Subtraction implements Calculator {@Overridepublic double calculate(double firstNumber, double secondNumber) {return firstNumber - secondNumber;}
}

4.3乘法

package com.lz.jsq.jjcc;import com.lz.jsq.jk.Calculator;/*** @author lz* @create 2023-09-11 9:14*/public class Multiplication implements Calculator {@Overridepublic double calculate(double firstNumber, double secondNumber) {return firstNumber * secondNumber;}
}

4.4除法

package com.lz.jsq.jjcc;import com.lz.jsq.jk.Calculator;/*** @author lz* @create 2023-09-11 9:15*/
public class Division implements Calculator {@Overridepublic double calculate(double firstNumber, double secondNumber) {if (secondNumber == 0) {throw new IllegalArgumentException("Division by Zero");}return firstNumber / secondNumber;}}

5.创建一个用于生成计算器实例的抽象工厂 CalculatorFactory

package com.lz.jsq.factory;/*** @author lz* @create 2023-09-11 9:18*/import com.lz.jsq.jk.Calculator;/*** 创建一个用于生成计算器实例的抽象工厂*/
public interface CalculatorFactory {Calculator createCalculator();
}

6.创建具体的工厂类 AdditionFactorySubtractionFactoryMultiplicationFactory 和 DivisionFactory 来生产相应的计算器实例

6.1加法工厂

package com.lz.jsq.factory;import com.lz.jsq.jjcc.Addition;
import com.lz.jsq.jk.Calculator;/*** @author lz* @create 2023-09-11 9:21*/
public class AdditionFactory implements CalculatorFactory {@Overridepublic Calculator createCalculator() {return new Addition();}
}

6.2减法工厂

package com.lz.jsq.factory;import com.lz.jsq.jjcc.Subtraction;
import com.lz.jsq.jk.Calculator;/*** @author lz* @create 2023-09-11 9:21*/
public class SubtractionFactory implements CalculatorFactory {@Overridepublic Calculator createCalculator() {return new Subtraction();}
}

6.3乘法工厂

package com.lz.jsq.factory;import com.lz.jsq.jjcc.Multiplication;
import com.lz.jsq.jk.Calculator;/*** @author lz* @create 2023-09-11 9:21*/
public class MultiplicationFactory implements CalculatorFactory {@Overridepublic Calculator createCalculator() {return new Multiplication();}
}

6.4除法工厂

package com.lz.jsq.factory;import com.lz.jsq.jjcc.Division;
import com.lz.jsq.jk.Calculator;/*** @author lz* @create 2023-09-11 9:21*/
public class DivisionFactory implements CalculatorFactory {@Overridepublic Calculator createCalculator() {return new Division();}
}

7.创建一个 CalculatorApp 类,它将使用 CalculatorFactory 来生成所需类型的 Calculator 实例

package com.lz.jsq.test;import com.lz.jsq.factory.*;
import com.lz.jsq.jk.Calculator;import java.util.Scanner;public class CalculatorApp {private CalculatorFactory calculatorFactory;public CalculatorApp(CalculatorFactory calculatorFactory) {this.calculatorFactory = calculatorFactory;}public double calculate(Calculator calculator, double firstNumber, double secondNumber) {return calculator.calculate(firstNumber, secondNumber);}public static void main(String[] args) {Scanner scanner = new Scanner(System.in);boolean shouldContinue = true;while (shouldContinue) {System.out.println("请选择要使用的计算器类型:");System.out.println("1. 加法");System.out.println("2. 减法");System.out.println("3. 乘法");System.out.println("4. 除法");CalculatorFactory calculatorFactory = null;int choice = scanner.nextInt();boolean isValidOption = true;switch (choice) {case 1:calculatorFactory = new AdditionFactory();break;case 2:calculatorFactory = new SubtractionFactory();break;case 3:calculatorFactory = new MultiplicationFactory();break;case 4:calculatorFactory = new DivisionFactory();break;default:System.out.println("无效的选项");isValidOption = false;}if (isValidOption) {boolean innerLoopShouldContinue = true;while (innerLoopShouldContinue) {System.out.print("请输入第一个数: ");double firstNumber = scanner.nextDouble();System.out.print("请输入第二个数: ");double secondNumber = scanner.nextDouble();CalculatorApp app = new CalculatorApp(calculatorFactory);double result = app.calculate(app.calculatorFactory.createCalculator(), firstNumber, secondNumber);System.out.println("结果为:" + result);System.out.print("是否要继续计算?输入 0 以退出当前运算,输入其他任意数字以继续:");int continueChoice = scanner.nextInt();if (continueChoice == 0) {innerLoopShouldContinue = false;}}}System.out.print("是否要继续选择运算类型?输入 0 以退出程序,输入其他任意数字以继续:");int mainContinueChoice = scanner.nextInt();if (mainContinueChoice == 0) {shouldContinue = false;}}scanner.close();}
}

8.展示效果图


http://www.ppmy.cn/news/1103730.html

相关文章

无涯教程-JavaScript - DDB函数

描述 DDB函数使用双倍余额递减法或您指定的某些其他方法返回指定期间内资产的折旧。 语法 DDB (cost, salvage, life, period, [factor])争论 Argument描述Required/OptionalCostThe initial cost of the asset.RequiredSalvage 折旧结束时的价值(有时称为资产的残值)。 该…

数据结构 - 双向链表

文章目录 目录 文章目录 前言 一、什么是双向链表? 双向链表有什么优势? 二、双向链表的设计和实现 1.设计思想 尾增 : 在链表的末尾添加新的元素 头插 : 在链表头部插入节点 删除 : 根据val的值删除节点 查找 : 根据索引的值查找并返回节点 总结 前言 大家好,今天给…

iOS开发Swift-12-列表UI,TableViewController,动态响应Button勾选-待办事项App(1)

1.创建新项目 为项目添加图标 2.将Table View Controller添加到界面中 将箭头移动到Table View上来,代表它是首页(根页面).选中ViewController,点击Delete,对它进行删除.将代码ViewController.swift也删除掉. 新建一个Cocoa Touch Class. 将TableViewController的cla…

第15章_瑞萨MCU零基础入门系列教程之Common I2C总线模块

本教程基于韦东山百问网出的 DShanMCU-RA6M5开发板 进行编写&#xff0c;需要的同学可以在这里获取&#xff1a; https://item.taobao.com/item.htm?id728461040949 配套资料获取&#xff1a;https://renesas-docs.100ask.net 瑞萨MCU零基础入门系列教程汇总&#xff1a; ht…

使用@RestControllerAdvice统一处理@ResponseBody的返回前端数据

一、前言 spring mvc下&#xff0c;在controller控制类中&#xff0c;标注了ResponseBody的方法正常来说返回的是json对象&#xff0c;有时候还想额外在特定条件下处理一些数据&#xff08;使用if&#xff09;&#xff0c;又或者是每个返回json数据的方法都可能需要做同样的处…

Nginx 配置错误导致漏洞

文章目录 Nginx 配置错误导致漏洞1. 环境启动2. CRLF注入漏洞2.1 漏洞描述2.2 漏洞原理2.3 漏洞利用2.4 修复建议 3. 目录穿越漏洞3.1 漏洞描述3.2 漏洞原理3.3 漏洞利用3.4 修复建议 4. add_header被覆盖4.1 漏洞描述4.2 漏洞原理4.3 漏洞利用4.4 修复建议 Nginx 配置错误导致…

ChatGPT是否可以用于虚拟心理治疗和心理健康支持?

ChatGPT可以用于虚拟心理治疗和心理健康支持&#xff0c;但在这个领域中存在一些关键的考虑因素和限制。在探讨这些问题之前&#xff0c;让我们先了解一下ChatGPT在心理健康领域的应用潜力。 ### ChatGPT在虚拟心理治疗中的应用潜力 虚拟心理治疗是一种利用计算机程序或虚拟助…

SpringCloud-Hystrix 服务降级与熔断

接上文SpringCloud-Feign 问题描述 为了解决上述情况&#xff0c;SpringCloud提供了Hystrix熔断器组件&#xff0c;如同保险丝。服务降级则不会直接返回错误&#xff0c;而是提供一个补救措施&#xff0c;正常响应给请求者。 1.服务降级 基于借阅管理服务&#xff0c;不开启…