java设计模式三

工厂模式是一种创建型设计模式,它提供了一个创建对象的接口,但允许子类决定实例化哪一个类。工厂模式有几种变体,包括简单工厂模式、工厂方法模式和抽象工厂模式。下面通过一个简化的案例和对Java标准库中使用工厂模式的源码分析来说明这一模式。

### 简单工厂模式案例

假设我们要创建不同类型的形状(Shape),如圆形(Circle)、正方形(Square)等,但不希望在客户端代码中直接使用`new`关键字来创建具体形状的对象,以保持代码的灵活性和扩展性。

首先定义一个`Shape`接口:

```java

public interface Shape {void draw();
}


```

然后创建几个实现这个接口的具体形状类:

```java

public class Circle implements Shape {@Overridepublic void draw() {System.out.println("Drawing Circle");}
}public class Square implements Shape {@Overridepublic void draw() {System.out.println("Drawing Square");}
}


```

接下来是简单工厂类,它负责根据输入创建具体的形状对象:

```java

public class ShapeFactory {public static Shape getShape(String shapeType) {if (shapeType == null) {return null;}if ("CIRCLE".equalsIgnoreCase(shapeType)) {return new Circle();} else if ("SQUARE".equalsIgnoreCase(shapeType)) {return new Square();}// 可以添加更多形状throw new IllegalArgumentException("Invalid shape type");}
}


```

客户端代码使用工厂来获取形状对象,而无需了解具体创建细节:

```java

public class SimpleFactoryDemo {public static void main(String[] args) {Shape circle = ShapeFactory.getShape("CIRCLE");circle.draw();Shape square = ShapeFactory.getShape("SQUARE");square.draw();}
}


```

### Java标准库中的工厂模式示例:`java.util.Calendar`

Java标准库中的`Calendar`类是一个使用工厂方法模式的例子。它提供了一个静态方法`getInstance()`,该方法返回一个`Calendar`实例,这个实例是根据系统的默认时区和语言环境创建的。

```java

public class Calendar {// 防止实例化private Calendar() {}public static Calendar getInstance() {return createCalendar(TimeZone.getDefaultRef(), Locale.getDefault(Locale.Category.FORMAT));}// 实际创建日历实例的私有方法private static Calendar createCalendar(TimeZone zone, Locale locale) {// 实现细节...}
}


```

在这个例子中,`getInstance()`方法就是工厂方法,它隐藏了`Calendar`实例的具体创建逻辑,使得客户端能够以一种统一且易于使用的方式获得`Calendar`对象,同时保持了系统的灵活性和扩展性。

以上展示了工厂模式的基本概念、一个简单的实现案例,以及在Java标准库中的应用示例。在实际应用中,根据项目的复杂度和需求,可以选择合适的工厂模式变体来设计代码结构。

### 工厂方法模式案例

工厂方法模式与简单工厂模式的主要区别在于,它为每个产品类提供一个对应的工厂类,这样做的好处是当需要添加新产品时,只需要添加相应的产品类和工厂类即可,不需要修改已有的代码,符合开闭原则。

假设我们扩展上面的形状例子,采用工厂方法模式:

首先,定义一个工厂接口:

```java

public interface ShapeFactory {Shape createShape();
}


```

然后,为每种形状创建对应的工厂类:

```java

public class CircleFactory implements ShapeFactory {@Overridepublic Shape createShape() {return new Circle();}
}public class SquareFactory implements ShapeFactory {@Overridepublic Shape createShape() {return new Square();}
}


```

客户端代码不再直接与具体工厂或产品交互,而是通过工厂接口操作:

```java

public class FactoryMethodDemo {public static void main(String[] args) {ShapeFactory circleFactory = new CircleFactory();Shape circle = circleFactory.createShape();circle.draw();ShapeFactory squareFactory = new SquareFactory();Shape square = squareFactory.createShape();square.draw();}
}


```

### 抽象工厂模式案例

抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

假设我们的图形系统除了形状外,还包含颜色。我们可以定义两个接口,一个是形状工厂,另一个是颜色工厂,然后创建一个抽象工厂来组合这两个工厂:

```java

public interface Color {void fill();
}public class Red implements Color {@Overridepublic void fill() {System.out.println("Filling with Red color");}
}// 省略其他颜色类...public interface AbstractFactory {Shape getShape(String shapeType);Color getColor(String colorType);
}public class ShapeColorFactory implements AbstractFactory {@Overridepublic Shape getShape(String shapeType) {// 实现与简单工厂类似,根据类型返回具体形状}@Overridepublic Color getColor(String colorType) {// 根据类型返回具体颜色}
}


```

客户端通过抽象工厂来获取形状和颜色:

```java

public class AbstractFactoryDemo {public static void main(String[] args) {AbstractFactory factory = new ShapeColorFactory();Shape shape = factory.getShape("CIRCLE");shape.draw();Color color = factory.getColor("RED");color.fill();}
}


```

### 总结

- **简单工厂模式**:一个工厂类负责所有产品的创建,易于使用但不便于扩展和维护。
- **工厂方法模式**:每个产品都有对应的工厂类,符合开闭原则,易于扩展,但会增加类的数量。
- **抽象工厂模式**:提供一个接口来创建一系列相关或相互依赖的对象,适合系统中有多组产品族的情况。

选择哪种工厂模式取决于项目需求的复杂度和预期的扩展性。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot3项目打包和运行

六、SpringBoot3项目打包和运行 6.1 添加打包插件 在Spring Boot项目中添加spring-boot-maven-plugin插件是为了支持将项目打包成可执行的可运行jar包。如果不添加spring-boot-maven-plugin插件配置,使用常规的java -jar命令来运行打包后的Spring Boot项目是无法找…

linux笔记--tmux的使用

目录 1--安装tmux 2--创建新会话 3--离开会话 4--查看所有会话 5--进入会话 6--结束会话 1--安装tmux # Ubuntu 或 Debian sudo apt-get install tmux# CentOS 或 Fedora sudo yum install tmux# Mac brew install tmux 2--创建新会话 tmux new -s <session-name&g…

scrapy常用命令总结

1.创建scrapy项目的命令&#xff1a;     scrapy startproject <项目名字> 示例&#xff1a;     scrapy startproject myspider 2.通过命令创建出爬虫文件&#xff0c;爬虫文件为主要的代码文件&#xff0c;通常一个网站的爬取动作都会在爬虫文件中进行编写。 …

Java学习第01天-Java基本内容

目录 单行注释 多行注释 文档注释&#xff08;GPT生成&#xff09; 字面量 分类 使用示例 变量 定义 定义格式 注意事项 数据类型分类 命名指导规范 补充 单行注释 public class note {public static void main(String[] args) {// 单行注释} }多行注释 publ…

FileBird Pro插件下载:革新您的WordPress媒体库管理

WordPress媒体库是您网站的重要组成部分&#xff0c;它存储了所有的图片、视频、文档等文件。但随着网站的扩展&#xff0c;媒体库的管理变得越来越复杂。FileBird Pro插件&#xff0c;作为一款专为WordPress用户设计的媒体库管理工具&#xff0c;以其直观的界面和强大的功能&a…

docker操作使用注意事项

文章目录 一、运行docker二、拉取的镜像存放位置1、查询所有拉取的镜像2、查询所有安装的镜像3、查询docker应用的所有信息 一、运行docker 该命令执行后是在窗口下运行的&#xff0c;关闭或退出后docker应用会停止运行 -p&#xff1a;设置绑定端口映射&#xff0c;10022对应…

JS中浅拷贝和深拷贝的区别

在JavaScript中&#xff0c;浅拷贝和深拷贝是用于复制对象或数组的两种常用方法。它们之间的区别在于复制的程度。 1.浅拷贝&#xff1a;浅拷贝是指创建一个新的对象或数组&#xff0c;将原始对象或数组的引用复制给新的对象或数组。这意味着原始对象和新的对象将共享相同的引…

Elastic 通过 AI 驱动的安全分析改变 SIEM 游戏

作者&#xff1a;Santosh Krishnan, Jennifer Ellard 借助由搜索 AI 提供支持的新攻击发现功能&#xff0c;优先考虑攻击&#xff0c;而不是警报。 传统的安全信息与事件管理系统&#xff08;SIEM&#xff09;在很大程度上依赖屏幕背后的人类才能取得成功。警报、仪表盘、威胁…

Python面向对象编程思想的深入学习

魔术方法的使用 案例体验 class Student:def __init__(self, name, age):self.name nameself.age age# __str__魔术方法, 如果不去写这个方法&#xff0c;那么print输出的则是信息存储的内存地址。def __str__(self):return fStudent类对象&#xff0c;name:{self.name}, ag…

【爬虫】fake_useragent的使用、BeautifulSoup(find()和find_all())

1 fake_useragent 2 BeautifulSoup 3 Beautiful Soup库的find()和find_all() 1 fake_useragent fake_useragent是一个Python库&#xff0c;用于生成随机的用户代理字符串。 用户代理是在HTTP请求中发送给服务器的一种标识&#xff0c;它告诉服务器发送请求的客户端的类型、版本…

PVZ2 植物克僵尸【第二期】

众所周知&#xff0c;PVZ2&#xff08;植物大战僵尸2&#xff09;中有许多恶心的僵尸&#xff0c;而我们不得不派出它们的————克星&#xff01;&#xff08;*为建议方法&#xff09; 5.战机小鬼 战机小鬼&#xff0c;恶心会发射子弹&#xff0c;所以&#xff1a; 1&…

Ubuntu18.04设置SSH密钥登录

我们一般使用 VSCode 、MobaXterm、PuTTY等 SSH 客户端来远程管理 Linux 服务器。但是&#xff0c;一般的密码方式登录&#xff0c;容易有密码被暴力破解的问题。所以&#xff0c;一般我们会将 SSH 的端口设置为默认的 22 以外的端口&#xff0c;或者禁用 root 账户登录。但是即…

Autosar NvM配置-手动配置Nvblock及使用-基于ETAS软件

文章目录 前言NvDataInterfaceNvBlockNvM配置SWC配置RTE Mapping使用生成的接口操作NVM总结前言 NVM作为存储协议栈中最顶层的模块,是必须要掌握的。目前项目基本使用MCU带的Dflash模块,使用Fee模拟eeprom。在项目前期阶段,应该充分讨论需要存储的内容,包括应用数据,诊断…

JSP企业快信系统的设计与实现参考论文(论文 + 源码)

【免费】JSP企业快信系统.zip资源-CSDN文库https://download.csdn.net/download/JW_559/89277688 JSP企业快信系统的设计与实现 摘 要 计算机网络的出现到现在已经经历了翻天覆地的重大改变。因特网也从最早的供科学家交流心得的简单的文本浏览器发展成为了商务和信息的中心…

OSPF邻居建立后学不到路由?新手做项目最容易犯这个错!

号主&#xff1a;老杨丨11年资深网络工程师&#xff0c;更多网工提升干货&#xff0c;请关注公众号&#xff1a;网络工程师俱乐部 你们好&#xff0c;我的网工朋友。 新手经常会在配置OSPF时遇到一些棘手的问题&#xff0c;比如由于接口网络类型配置不一致导致的邻居关系建立失…

【C++ 关键字】const 关键字详解

文章目录 1. const 概念2.常量指针 和 指针常量 的区别2.1 常量指针&#xff08;底层 const&#xff09;2.2 指针常量 (顶层 const) 3.const 关键字的作用4.const 和 define 的区别5.const 总结 1. const 概念 const 是一个关键字&#xff0c;被修饰的值不能改变&#xff0c;是…

通过 Java 操作 redis -- 连接 redis

如果我们想在本地主机上访问 Linux 服务器上的 redis &#xff0c;我们就需要通过 ssh 进行端口转发&#xff0c;推荐看 本地主机访问服务器的Redis -- 配置 ssh 端口转发 通过 Java 操作 redis 已经有大佬创建了很多第三方库&#xff0c;这里我们使用 jedis &#xff0c;因为它…

Git系列:git push (-u) 与 git branch (-u)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

硬盘惊魂!文件夹无法访问怎么办?

在数字时代&#xff0c;数据的重要性不言而喻。然而&#xff0c;有时我们会遇到一个令人头疼的问题——文件夹提示无法访问。当你急需某个文件夹中的文件时&#xff0c;却被告知无法打开&#xff0c;这种感受真是难以言表。今天&#xff0c;我们就来深入探讨这个问题&#xff0…

FPGA学习笔记(3)——正点原子ZYNQ7000简介

1 ZYNQ-7000简介 ZYNQ 是由两个主要部分组成的&#xff1a;一个由双核 ARM Cortex-A9 为核心构成的处理系统&#xff08;PS&#xff0c;Processing System&#xff09;&#xff0c;和一个等价于一片 FPGA 的可编程逻辑&#xff08;PL&#xff0c;Programmable Logic&#xff0…