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

设计模式使用场景实现示例及优缺点(创建型模式——单例模式、建造者模式、原型模式)

创建型模式

单例模式(Singleton Pattern)

单例模式(Singleton Pattern)在Java中的使用场景与在其他编程语言中类似,其主要目的是确保一个类只有一个实例,并提供一个全局的访问点。以下是单例模式的一些常见使用场景及详细讲解:

使用场景

  1. 控制资源的使用

    • 数据库连接池:数据库连接是昂贵的资源,使用单例模式可以确保只有一个连接池实例,统一管理连接资源,避免重复创建和销毁连接,提高系统性能。
    • 线程池:线程的创建和销毁开销较大,单例模式可以确保只有一个线程池实例,集中管理线程,提高系统效率。
  2. 全局配置管理

    • 配置文件管理:系统中的配置通常是全局的,使用单例模式可以确保配置文件只被加载一次,并且全局共享,避免多次加载造成的资源浪费。
    • 日志管理器:日志系统在应用程序中通常是全局的,通过单例模式可以确保日志管理器实例的唯一性,方便统一管理日志输出。
  3. 状态管理

    • 缓存管理:在某些系统中,需要对一些数据进行缓存,使用单例模式可以确保缓存管理器实例的唯一性,从而保证缓存的一致性和统一管理。
    • 设备管理:对于一些物理设备,如打印机或串口设备,通过单例模式可以确保设备管理器的唯一实例,避免设备被多个对象同时操作。

实现示例(Java)

下面是一个在Java中实现单例模式的示例:

饿汉式单例模式

饿汉式单例模式在类加载时就创建实例:

public class Singleton {// 在类加载时创建实例private static final Singleton INSTANCE = new Singleton();// 私有化构造函数,防止外部实例化private Singleton() {}// 提供一个公共的访问方法public static Singleton getInstance() {return INSTANCE;}
}
懒汉式单例模式

懒汉式单例模式在需要时才创建实例:

public class Singleton {// 初始时不创建实例private static Singleton instance;// 私有化构造函数,防止外部实例化private Singleton() {}// 提供一个公共的访问方法,并使用 synchronized 关键字确保线程安全public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}
双重检查锁定(Double-Checked Locking)

这种方式通过双重检查加锁,确保线程安全并提高效率:

public class Singleton {// 使用 volatile 关键字确保多线程环境下变量的可见性private static volatile Singleton instance;// 私有化构造函数,防止外部实例化private Singleton() {}// 提供一个公共的访问方法public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}
}

使用示例

public class Main {public static void main(String[] args) {Singleton singleton1 = Singleton.getInstance();Singleton singleton2 = Singleton.getInstance();singleton1.value = 42;System.out.println(singleton2.value); // 输出 42,证明两个引用指向同一个实例}
}

通过上述示例,可以看出无论是饿汉式、懒汉式还是双重检查锁定,单例模式都可以确保一个类只有一个实例,并在需要时提供全局访问点。这在实际应用中有助于资源管理、状态管理和配置管理等。

建造者模式(Builder Pattern)

建造者模式(Builder Pattern)是一种创建型设计模式,它允许你分步骤创建复杂对象。通过将一个复杂对象的构造代码从其表示中分离出来,建造者模式可以让你通过细化各个部分的构造步骤来创建一个复杂对象。

适用场景

  1. 需要生成的对象有复杂的内部结构

    • 对象的创建过程包含多个步骤或多个部件的创建。
  2. 同样的创建过程需要生成不同的表示

    • 一个构建过程可以创建多个不同类型的对象。
  3. 客户端代码不希望直接控制对象的创建过程

    • 客户端代码只需要一个构建器来控制创建的细节。

实现示例(Java)

以下是一个简单的建造者模式的实现示例,展示如何创建不同类型的房子(如石头房子和木头房子)。

1. 产品类
public class House {private String foundation;private String structure;private String roof;private String interior;public void setFoundation(String foundation) {this.foundation = foundation;}public void setStructure(String structure) {this.structure = structure;}public void setRoof(String roof) {this.roof = roof;}public void setInterior(String interior) {this.interior = interior;}@Overridepublic String toString() {return "House [foundation=" + foundation + ", structure=" + structure + ", roof=" + roof + ", interior=" + interior + "]";}
}
2. 抽象建造者类
public abstract class HouseBuilder {protected House house;public House getHouse() {return house;}public void createNewHouse() {house = new House();}public abstract void buildFoundation();public abstract void buildStructure();public abstract void buildRoof();public abstract void buildInterior();
}
3. 具体建造者类
public class StoneHouseBuilder extends HouseBuilder {@Overridepublic void buildFoundation() {house.setFoundation("Stone foundation");}@Overridepublic void buildStructure() {house.setStructure("Stone walls");}@Overridepublic void buildRoof() {house.setRoof("Stone roof");}@Overridepublic void buildInterior() {house.setInterior("Stone interior");}
}public class WoodenHouseBuilder extends HouseBuilder {@Overridepublic void buildFoundation() {house.setFoundation("Wooden foundation");}@Overridepublic void buildStructure() {house.setStructure("Wooden walls");}@Overridepublic void buildRoof() {house.setRoof("Wooden roof");}@Overridepublic void buildInterior() {house.setInterior("Wooden interior");}
}
4. 指挥者类
public class Director {private HouseBuilder houseBuilder;public void setHouseBuilder(HouseBuilder houseBuilder) {this.houseBuilder = houseBuilder;}public House getHouse() {return houseBuilder.getHouse();}public void constructHouse() {houseBuilder.createNewHouse();houseBuilder.buildFoundation();houseBuilder.buildStructure();houseBuilder.buildRoof();houseBuilder.buildInterior();}
}
5. 客户端代码
public class Client {public static void main(String[] args) {Director director = new Director();// 建造石头房子HouseBuilder stoneHouseBuilder = new StoneHouseBuilder();director.setHouseBuilder(stoneHouseBuilder);director.constructHouse();House stoneHouse = director.getHouse();System.out.println("House built:\n" + stoneHouse);// 建造木头房子HouseBuilder woodenHouseBuilder = new WoodenHouseBuilder();director.setHouseBuilder(woodenHouseBuilder);director.constructHouse();House woodenHouse = director.getHouse();System.out.println("House built:\n" + woodenHouse);}
}

注释说明

  1. 产品类

    • House 类表示一个复杂对象。它有多个部件(如基础、结构、屋顶和内部装饰)。
  2. 抽象建造者类

    • HouseBuilder 是一个抽象类,定义了构建 House 对象的各个步骤(如 buildFoundationbuildStructure 等)。
  3. 具体建造者类

    • StoneHouseBuilderWoodenHouseBuilder 是具体的建造者类,实现了抽象建造者类的方法,具体定义了如何构建 House 的各个部件。
  4. 指挥者类

    • Director 类负责管理建造过程。它通过调用 HouseBuilder 的方法来一步步构建 House 对象。
  5. 客户端代码

    • Client 类通过 Director 类来构建不同类型的房子。客户端代码不需要直接控制对象的创建过程,只需要使用 Director 来管理建造者。

总结

建造者模式通过将复杂对象的构建过程分离出来,使得客户端代码可以灵活地构建不同类型的对象。它适用于需要构建复杂对象的场景,尤其是当对象的创建过程包含多个步骤或多个部件时。建造者模式可以提高代码的可读性和可维护性。

原型模式(Prototype Pattern)

原型模式(Prototype Pattern)是一种创建型设计模式,它允许一个对象通过克隆自身来创建新的对象。使用原型模式,可以避免创建对象时涉及复杂的初始化步骤,同时也可以方便地复制已有对象的状态。

适用场景

  1. 对象的创建成本很高

    • 当对象的创建成本很高,且可以通过复制来减少成本时,可以使用原型模式。
  2. 对象的初始化复杂

    • 对象的初始化需要很多步骤,而这些步骤又可能会有所变化,使用原型模式可以简化这些步骤。
  3. 需要大量相似对象

    • 当需要大量相似对象时,可以通过复制原型来快速创建新对象。

实现示例(Java)

以下是一个简单的原型模式的实现示例,展示如何克隆不同类型的形状(如圆形和矩形)。

1. 定义原型接口
public interface Shape extends Cloneable {Shape clone();void draw();
}
2. 具体原型类实现接口
public class Circle implements Shape {private int radius;public Circle(int radius) {this.radius = radius;}@Overridepublic Circle clone() {return new Circle(this.radius);}@Overridepublic void draw() {System.out.println("Drawing a circle with radius: " + radius);}
}public class Rectangle implements Shape {private int width;private int height;public Rectangle(int width, int height) {this.width = width;this.height = height;}@Overridepublic Rectangle clone() {return new Rectangle(this.width, this.height);}@Overridepublic void draw() {System.out.println("Drawing a rectangle with width: " + width + " and height: " + height);}
}
3. 客户端代码
public class Client {public static void main(String[] args) {// 创建原型对象Circle originalCircle = new Circle(5);Rectangle originalRectangle = new Rectangle(3, 4);// 克隆对象Circle clonedCircle = originalCircle.clone();Rectangle clonedRectangle = originalRectangle.clone();// 使用克隆对象originalCircle.draw();clonedCircle.draw();originalRectangle.draw();clonedRectangle.draw();}
}

注释说明

  1. 原型接口

    • Shape 接口继承了 Cloneable 接口,并定义了 clonedraw 方法。clone 方法用于克隆对象,draw 方法用于绘制形状。
  2. 具体原型类

    • CircleRectangle 类实现了 Shape 接口,并提供了自己的 clonedraw 方法。
    • clone 方法使用当前对象的状态创建一个新对象。
  3. 客户端代码

    • Client 类创建了原型对象(如 CircleRectangle),然后通过调用 clone 方法克隆这些对象,并使用克隆的对象。

总结

原型模式通过克隆现有对象来创建新对象,适用于对象创建成本高、初始化复杂或需要大量相似对象的场景。它能够简化对象创建过程,提高代码的灵活性和可维护性。

相关文章:

设计模式使用场景实现示例及优缺点(创建型模式——单例模式、建造者模式、原型模式)

创建型模式 单例模式(Singleton Pattern) 单例模式(Singleton Pattern)在Java中的使用场景与在其他编程语言中类似,其主要目的是确保一个类只有一个实例,并提供一个全局的访问点。以下是单例模式的一些常…...

LAMP万字详解(概念、构建步骤)

目录 LAMP Apache 起源 主要特点 软件版本 编译安装httpd服务器 编译安装的优点 操作步骤 准备工作 编译 安装 优化执行路径 添加服务 守护进程 配置httpd 查看 Web 站点的访问情况 虚拟主机 类型 部署基于域名的虚拟主机 为虚拟主机提供域名解析&#xff…...

金南瓜科技SECS/GEM:引领智能制造新潮流

引言 在当今快速发展的半导体行业中,智能制造和自动化生产已成为提升效率和降低成本的关键。金南瓜科技凭借其先进的SECS/GEM解决方案,正成为这一变革的先锋。 SECS/GEM:智能制造的核心 SECS/GEM(SEMI Equipment Communications …...

昇思训练营打卡第二十一天(DCGAN生成漫画头像)

DCGAN,即深度卷积生成对抗网络(Deep Convolutional Generative Adversarial Network),是一种深度学习模型,由Ian Goodfellow等人在2014年提出。DCGAN在生成对抗网络(GAN)的基础上,引…...

东方通Tongweb发布vue前端

一、前端包中添加文件 1、解压vue打包文件 以dist.zip为例,解压之后得到dist文件夹,进入dist文件夹,新建WEB-INF文件夹,进入WEB-INF文件夹,新建web.xml文件, 打开web.xml文件,输入以下内容 …...

spring xml实现bean对象(仅供自己参考)

对于spring xml来实现bean 具体代码&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaL…...

MiniGPT-Med 通用医学视觉大模型:生成医学报告 + 视觉问答 + 医学疾病识别

MiniGPT-Med 通用医学视觉大模型&#xff1a;生成医学报告 视觉问答 医学疾病识别 提出背景解法拆解 论文&#xff1a;https://arxiv.org/pdf/2407.04106 代码&#xff1a;https://github.com/Vision-CAIR/MiniGPT-Med 提出背景 近年来&#xff0c;人工智能&#xff08;AI…...

如何判断ip地址在同一个网段:技术解析与实际应用

在网络世界中&#xff0c;IP地址就像每个人的身份证一样&#xff0c;是识别和定位网络设备的关键。然而&#xff0c;仅仅知道IP地址还不足以完全理解其背后的网络结构和通信方式。特别是当我们需要判断两个或多个IP地址是否位于同一网段时&#xff0c;就需要借助子网掩码这一概…...

linux高级编程(TCP)(传输控制协议)

TCP与UDP: TCP: TCP优点&#xff1a; 可靠&#xff0c;稳定 TCP的可靠体现在TCP在传递数据之前&#xff0c;会有三次握手来建立连接&#xff0c;而且在数据传递时&#xff0c;有确认、窗口、重传、拥塞控制机制&#xff0c;在数据传完后&#xff0c;还会断开连接用来节约系统…...

【常见开源库的二次开发】一文学懂CJSON

简介&#xff1a; JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式。它基于JavaScript的一个子集&#xff0c;但是JSON是独立于语言的&#xff0c;这意味着尽管JSON是由JavaScript语法衍生出来的&#xff0c;它可以被任何编程语言读取和生成…...

点云下采样有损压缩

转自本人博客&#xff1a;点云下采样有损压缩 点云下采样是通过一定规则对原点云数据进行再采样&#xff0c;减少点云个数&#xff0c;降低点云稀疏程度&#xff0c;减小点云数据大小。 1. 体素下采样&#xff08;Voxel Down Sample&#xff09; std::shared_ptr<PointClo…...

AutoHotKey自动热键(六)转义符号

转义符号 符号说明,, (原义的逗号). 注意: 在命令最后一个参数中的逗号不需要转义, 因为程序知道把它们作为原义处理. 对于 MsgBox 所有参数同样如此, 因为它会智能的处理逗号.%% (原义的百分号) (原义的重音符; 即两个连续的转义符产生单个原义字符);; (原义的分号). 注意: 仅…...

第16章 主成分分析:四个案例及课后习题

1.假设 x x x为 m m m 维随机变量&#xff0c;其均值为 μ \mu μ&#xff0c;协方差矩阵为 Σ \Sigma Σ。 考虑由 m m m维随机变量 x x x到 m m m维随机变量 y y y的线性变换 y i α i T x ∑ k 1 m α k i x k , i 1 , 2 , ⋯ , m y _ { i } \alpha _ { i } ^ { T } …...

股票分析系统设计方案大纲与细节

股票分析系统设计方案大纲与细节 一、引言 随着互联网和金融行业的迅猛发展,股票市场已成为重要的投资渠道。投资者在追求财富增值的过程中,对股票市场的分析和预测需求日益增加。因此,设计并实现一套高效、精准的股票分析系统显得尤为重要。本设计方案旨在提出一个基于大…...

.gitmodules文件

.gitmodules文件在Git仓库中的作用 .gitmodules 文件是 Git 版本控制系统中用来跟踪和管理子模块的配置文件。子模块允许你将一个 Git 仓库嵌套在另一个仓库中&#xff0c;这样可以方便地管理多个项目之间的依赖关系。 在 .gitmodules 文件中&#xff0c;通常会记录每个子模块…...

STM32 SPI世界:W25Q64 Flash存储器的硬件与软件集成策略

摘要 在嵌入式系统设计中&#xff0c;选择合适的存储解决方案对于确保数据的安全性和系统的可靠性至关重要。W25Q64 Flash存储器因其高性能和大容量成为STM32微控制器项目中的热门选择。本文将深入探讨STM32与W25Q64 Flash存储器的硬件连接、软件集成以及SPI通信的最佳实践。 …...

【计算机网络仿真】b站湖科大教书匠思科Packet Tracer——实验17 开放最短路径优先OSPF

一、实验目的 1.验证OSPF协议的作用&#xff1b; 二、实验要求 1.使用Cisco Packet Tracer仿真平台&#xff1b; 2.观看B站湖科大教书匠仿真实验视频&#xff0c;完成对应实验。 三、实验内容 1.构建网络拓扑&#xff1b; 2.验证OSPF协议的作用。 四、实验步骤 1.构建网…...

ChatGPT对话:python程序模拟操作网页弹出对话框

【编者按】单击一网页中的按钮&#xff0c;弹出对话框网页&#xff0c;再单击其中的“Yes”按钮&#xff0c;对话框关闭&#xff0c;请求并获取新网页。 可能ChatGPT第一次没有正确理解描述问题的含义&#xff0c;再次说明后&#xff0c;程序编写就正确了。 1问&#xff1a;pyt…...

利用亚马逊云科技云原生Serverless代码托管服务开发OpenAI ChatGPT-4o应用

今天小李哥继续介绍国际上主流云计算平台亚马逊云科技AWS上的热门生成式AI应用开发架构。上次小李哥分享​了利用谷歌云serverless代码托管服务Cloud Functions构建Gemini Pro API​&#xff0c;这次我将介绍如何利用亚马逊的云原生服务Lambda调用OpenAI的最新模型ChatGPT 4o。…...

Selenium 切换 frame/iframe

环境&#xff1a; Python 3.8 selenium3.141.0 urllib31.26.19说明&#xff1a; driver.switch_to.frame() # 将当前定位的主体切换为frame/iframe表单的内嵌页面中 driver.switch_to.default_content() # 跳回最外层的页面# 判断元素是否在 frame/ifame 中 # 126 邮箱为例 # …...

SkyWalking 10.2.0 SWCK 配置过程

SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外&#xff0c;K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案&#xff0c;全安装在K8S群集中。 具体可参…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

为什么要创建 Vue 实例

核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...

在 Spring Boot 项目里,MYSQL中json类型字段使用

前言&#xff1a; 因为程序特殊需求导致&#xff0c;需要mysql数据库存储json类型数据&#xff0c;因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...

git: early EOF

macOS报错&#xff1a; Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...

解析两阶段提交与三阶段提交的核心差异及MySQL实现方案

引言 在分布式系统的事务处理中&#xff0c;如何保障跨节点数据操作的一致性始终是核心挑战。经典的两阶段提交协议&#xff08;2PC&#xff09;通过准备阶段与提交阶段的协调机制&#xff0c;以同步决策模式确保事务原子性。其改进版本三阶段提交协议&#xff08;3PC&#xf…...