创建型设计模式合集

在本文章开始之前先说明:

设计模式不是代码,是某类问题的通用解决放啊,本质是用来提高 软件的维护性、通用性、扩展性,并且降低软件的复杂度 。

进入正题:

已知创建者模式分为以下5种:

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

单例模式

点击下面链接进入

设计模式——单例模式8种实现-CSDN博客

工厂模式

设计模式——三大工厂模式-CSDN博客

原型模式

介绍

原型模式是一种创建型设计模式,它允许创建对象的同时保持其内部状态的一份拷贝,从而避免了使用详细的构造函数和初始化过程。

个人理解:

就是通过克隆已有的对象,来创建新的对象,从而减少对象实例化过程。

原型模式中的浅拷贝和深拷贝

1、浅拷贝:
在对对象进行拷贝的时候,只会拷贝它的基本数据类型,引用数据类型只会对其引用


2、深拷贝
在对一个对象进行拷贝的时候,拷贝整个对象,不论基本数据类型和引用数据类型

代码示例

1、浅拷贝实例

如下实例,Sheep类通过集成Cloneable接口,实现直接浅拷贝功能(克隆)。

// 创建一个实现 Cloneable 接口的原型类
class Sheep implements Cloneable {private String name;public Sheep(String name) {this.name = name;}public String getName() {return name;}// 重写 clone 方法实现深拷贝@Overridepublic Sheep clone() {try {return (Sheep) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();return null;}}
}public class PrototypePatternExample {public static void main(String[] args) {Sheep originalSheep = new Sheep("Dolly");// 使用原型对象的 clone 方法复制一个新对象Sheep clonedSheep = originalSheep.clone();System.out.println("Original sheep: " + originalSheep.getName());System.out.println("Cloned sheep: " + clonedSheep.getName());}
}

 2、深拷贝实例

(下面只是一种实现深拷贝的方式,还有一种可以使用序列化实现深克隆)

下面使用对clone方法进行重写,实现深拷贝对象功能。

// 创建一个包含引用类型成员变量的原型类
class Person implements Cloneable {private String name;private Address address;public Person(String name, Address address) {this.name = name;this.address = address;}public String getName() {return name;}public Address getAddress() {return address;}@Overridepublic Person clone() {try {Person clonedPerson = (Person) super.clone();// 对引用类型成员变量进行深拷贝clonedPerson.address = this.address.clone();return clonedPerson;} catch (CloneNotSupportedException e) {e.printStackTrace();return null;}}
}// 创建包含引用类型成员变量的另一个类
class Address implements Cloneable {private String city;public Address(String city) {this.city = city;}public String getCity() {return city;}@Overridepublic Address clone() {try {return (Address) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();return null;}}
}public class DeepCopyExample {public static void main(String[] args) {Address originalAddress = new Address("Beijing");Person originalPerson = new Person("Alice", originalAddress);// 使用原型对象的 clone 方法进行深拷贝Person clonedPerson = originalPerson.clone();// 修改原始对象的地址originalAddress.setCity("Shanghai");// 输出克隆对象的地址,验证是否进行了深拷贝System.out.println("Original person's address: " + originalPerson.getAddress().getCity());System.out.println("Cloned person's address: " + clonedPerson.getAddress().getCity());}
}

小结和补充

优点

1、减少对象的创建时间
2、隐藏对象的创建细节:使得对象的创建过程更加简洁和易于维护。
3、动态改变对象的状态:在运行时可以修改对象的属性或内部状态,而无需通过重新实例化新对象来实现,使得系统更加灵活。


缺点

1、需要为每一个类配置一个克隆方法,需要修改其源码,违反了ocp原则
2、需要实现 Cloneable 接口:在 Java 中,被克隆的类需要实现 Cloneable 接口,并重写 clone 方法,这在某些情况下会增加代码的复杂性。
3、深拷贝问题:如果对象内部包含了引用类型的成员变量,克隆时需要注意深拷贝,否则可能会导致对象之间的关联性问题

补充

在 Spring 框架中,原型模式通常被用于创建 bean 实例。Spring 容器中的 bean 实例可以分为两种类型:单例和原型。单例 bean 是在容器启动时创建的,并且在整个应用程序生命周期中都只存在一个实例。而原型 bean 则是在每次请求时都会创建一个新的实例。

<bean id="myPrototypeBean" class="com.example.MyPrototypeBean" scope="prototype"/>
 

建造者模式

介绍

1、建造者模式又称生成器模式,是一种对象构建模式,可以将复杂对象的构建过程抽象出来,使这个抽象过程的不同实现方法可以构造出不同属性的对象。


2、建造者模式是一步一步创建一个复杂对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部实现细节。

为什么会有建造者模式

(可以说建造者模式的目的)

1、为了更好构建复杂对象
2、分离构建过程和表示
3、提供更好的控制构建过程
4、支持构建不同表示的对象
5、提高代码复用性

建造者模式的4个角色

  • Product(产品角色):一个具体的产品对象

  • Builder(抽象建造者):创建一个Product对象的各个部件指定的接口/抽象类。

  • ConcreteBuilder(具体建造者):实现接口,构建和装配各个部件

  • Director(指挥官):构建一个使用Builder接口的对象,它主要是用于创建一个复杂的对象。它主要有两个作用,一是:隔离客户与对象的生产过程;二是:复杂控制产品对象的生产过程。

实例

下面是一个Car的产品角色,CarBuilder就是车的各个部件(接口类),通过ConcreteCarBuilder 继承CarBuilder接口实现具体部件从而的得到车。可以在测试类(Director)中构建实现这个车

抽象建造者

public interface CarBuilder {void buildBody();void buildEngine();void buildTires();Car getCar();
}

 具体建造者

public class ConcreteCarBuilder implements CarBuilder {private Car car;public ConcreteCarBuilder() {this.car = new Car();}@Overridepublic void buildBody() {car.setBody("Sedan");}@Overridepublic void buildEngine() {car.setEngine("V6");}@Overridepublic void buildTires() {car.setTires("All-Season");}@Overridepublic Car getCar() {return car;}
}

产品

public class Car {private String body;private String engine;private String tires;public void setBody(String body) {this.body = body;}public void setEngine(String engine) {this.engine = engine;}public void setTires(String tires) {this.tires = tires;}public void showInfo() {System.out.println("Car: " + body + ", " + engine + ", " + tires);}
}

指挥者

public class CarBuilderExample {public static void main(String[] args) {CarBuilder carBuilder = new ConcreteCarBuilder();// 构建汽车对象carBuilder.buildBody();carBuilder.buildEngine();carBuilder.buildTires();// 获取构建完成的汽车对象Car car = carBuilder.getCar();// 展示汽车信息car.showInfo();}
}

建造者模式在JDK中使用

  • StringBuilder

1、Appendable接口定义了多个append方法(抽象方法),即Appendable为抽象建造者定义了抽象方法

2、AbstractStringBuilder 已经是建造者,只是不能实例化

3、StringBuilder 即充当了指挥者,也充当了具体的建造者。建造方法的实现是由AbstractStringBuilder 完成,而StringBuilder继承了AbstractStringBuilder。

  • Product(产品角色):StringBuilder

  • Builder(抽象建造者):Appendable接口

  • ConcreteBuilder(具体建造者):AbstractStringBuilder抽象类

  • Director(指挥官):StringBuilder

小结

优点

1、分离构建过程与表示:
建造者模式将复杂对象的构建过程与最终表示分离,使得可以更加灵活地构建不同结构的对象。
​
2、更好的控制构建过程:
通过建造者模式,可以逐步构建复杂对象,每一步都可以有不同的实现,从而更好地控制构建过程。
​
3、易于扩展:
由于建造者模式将构建过程和最终产品分离,因此很容易添加新的具体建造者来构建不同类型的产品,而不需要修改现有代码。
​
4、提高代码复用性:
可以在不同的场景下重复使用相同的构建逻辑,提高代码复用性。

2、缺点

1、增加了代码量:
引入建造者模式会增加代码量,因为需要定义抽象建造者、具体建造者等额外的类。
​
2、可能会导致对象过于复杂:
如果产品本身比较简单,引入建造者模式可能会显得过于繁琐,不值得。

最后的总结

个人的理解:

1、单例模式就是一个类只能有一个实例对象;

2、工厂模式就是通过条件,生成统一的类对象;

3、原型模式就是通过克隆复制对象来实现快速获取一个对象;

4、建造者模式就是对一个复杂类的一步步具体拆分实现

  1. 单例模式(Singleton Pattern)

    • 单例模式确保一个类只有一个实例,并提供一个全局访问点。这对于需要共享资源的对象或控制对象的创建数量很有用。
  2. 工厂模式(Factory Pattern)

    • 工厂模式通过使用工厂方法来创建对象,而无需指定将要创建的对象的具体类。这样可以根据特定条件或参数创建相应的对象实例。
  3. 原型模式(Prototype Pattern)

    • 原型模式通过克隆(复制)现有对象来创建新对象。这种方式可以避免重复初始化成本高的对象,提高性能。
  4. 建造者模式(Builder Pattern)

    • 建造者模式用于创建一个复杂对象,将其构建过程与表示分离,使得同样的构建过程可以创建不同的表示。通常在创建具有多个部分或配置选项的对象时使用。

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

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

相关文章

java实现文件上传到本地

很多时候我们都需要进行文件上传和下载的操作&#xff0c;具体怎么实现网上的代码其实也是挺多的&#xff0c;刚好我的项目中也遇到了文件上传和下载的需求&#xff0c;本篇博文具体讲解上传操作&#xff0c;下篇博文讲解下载操作。 我们具体来想一想要将一个从前端传来的文件…

Servlet快速入门

什么是Servlet? Servlet可以用很多方式来描述&#xff0c;这取决于上下文。 是一种技术&#xff0c;它被用来创建一个Web应用程序。 是一个API&#xff0c;它提供了许多接口和类&#xff0c;包括文档。 是一个接口&#xff0c;创建任何Serwlet都必须实现这个接口。 是一个扩展…

Python影像变化监测-跟踪大盐湖的萎缩

使用 Google Colab 中的 Python 分析 Landsat-8 图像(2014-2023)以创建大盐湖表面区域的时间序列 目录 🌅大盐湖萎缩问题简介💾下载 Landsat-8 图像📈统计文件中的大盐湖地区时间序列⚙️处理 Landsat-8 图像🗺️大盐湖图像的可视化🎥 大盐湖缩小的延时摄影📉大盐…

设计模式—单例模式

单例模式&#xff08;Singleton Pattern&#xff09;是一种常用的软件设计模式&#xff0c;其核心思想是确保一个类仅有一个实例&#xff0c;并提供一个全局访问点来获取这个实例。单例模式主要用于控制资源的访问&#xff0c;比如配置文件的读取&#xff0c;数据库的连接等&am…

Python中的if __name__ == ‘__main__‘ 是啥?

一.前言 Python模块和脚本的概述&#xff1a; 在开始解释 if __name__ __main__ 之前&#xff0c;我们先来了解一下 Python 中的模块和脚本的概念。Python 模块是一个包含 Python 代码的文件&#xff0c;可以被其他程序导入和重用。Python 脚本是可执行的 Python 代码文件&am…

通过联合部署DDoS高防和WAF提升网站防护能力

如果您的网站遭受的攻击既有流量型攻击&#xff0c;又混杂精巧的Web应用层攻击时&#xff08;例如SQL注入、跨站脚本攻击、命令注入等&#xff09;时&#xff0c;推荐您组合使用阿里云DDoS高防和Web 应用防火墙 WAF&#xff08;Web Application Firewall&#xff09;&#xff0…

C语言文件操作,linux文件操作,文件描述符,linux下一切皆文件,缓冲区,重定向

目录 C语言文件操作 如何打开文件以及打开文件方式 读写文件 关闭文件 Linux系统下的文件操作 open 宏标志位 write&#xff0c;read&#xff0c;close&#xff0c;lseek接口 什么是当前路径&#xff1f; linux下一切皆文件 文件描述符 文件描述符排序 C语言文件操…

杭州某国企 Java 面经

杭州某国企 Java 面经 面试官&#xff1a;这边收到你的xxx简历&#xff0c;现在方便做一个简单的面试沟通吗&#xff1f; 我&#xff1a;方便的方便的&#xff0c;内心OS&#xff1a;面经1。 1&#xff09; 面试官&#xff1a;先做个自我介绍吧 我&#xff1a;常规操作&am…

文件流的操作常识与限制

C语言的C库提供了文件流的各种操作方法&#xff0c;在这里介绍一些操作常识与限制。 示例&#xff1a; /*brief whats the limits of stream? show you hereauthor wenxuanpeiemail 15873152445163.com(query for any question here) */ #include <stdio.h>//<cstdi…

【音视频开发好书推荐1】《RTC程序设计:实时音视频权威指南》

1、WebRTC概述 WebRTC&#xff08;Web Real-Time Communication&#xff09;是一个由Google发起的实时音视频通讯C开源库&#xff0c;其提供了音视频采集、编码、网络传输&#xff0c;解码显示等一整套音视频解决方案&#xff0c;我们可以通过该开源库快速地构建出一个音视频通…

HTTP代理出现错误是什么原因?如何解决?

HTTP代理是一种常见的工具&#xff0c;可以帮助我们隐藏真实的IP地址&#xff0c;提高网络访问速度&#xff0c;突破网络限制等。但是&#xff0c;在使用过程中&#xff0c;HTTP代理可能会遇到各种问题&#xff0c;导致HTTP代理出现错误。这些错误是什么原因造成的&#xff0c;…

牛客练习赛122

D:圆 正着求删除的最小代价不好做&#xff0c;采用逆向思维&#xff0c;求选择一些不相交的线段使得构成一个圆的代价尽量大&#xff0c;最后答案就是所有线段权值之和减去最大代价。 那么如何求这个最大代价呢&#xff1f;显然区间DP 老套路&#xff1a;破环成链&#xff0…

详解Java中集合的List接口实现的ArrayList方法 | Set接口实现的HashSet方法

集合的概念 当我们需要保存一组一样&#xff08;类型相同&#xff09;的元素的时候&#xff0c;我们应该使用一个容器来存储&#xff0c;数组就是这样一个容器。 ● 数组的特点&#xff1a; 数组是一组数据类型相同的元素集合&#xff1b; 创建数组时&#xff0c;必须给定…

Discuz IIS上传附件大于28M失败报错Upload Failed.修改maxAllowedContentLength(图文教程)

下图&#xff1a;Discuz X3.5的系统信息&#xff0c;上传许可为1024MB(1GB) 论坛为局域网论坛&#xff0c;仅供内部同事交流使用&#xff01; 使用官方最新的Discuz! X3.5 Release 20231221 UTF-8 下图&#xff1a;选择上传附件&#xff08;提示可以最大上传100M&#xff09;…

【Python】新手入门(2):避免将关键字作为标识符

Python新手入门&#xff08;2&#xff09;&#xff1a;避免将关键字作为标识符 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1…

保护模式笔记九 中断门和IDT(中断描述符表)

段选择子&#xff1a; 先直观认识一下GDT和段选择子在逻辑地址转换为线性地址中的作用&#xff0c;例如&#xff1a; 给出逻辑地址&#xff1a;21h:12345678h&#xff0c;需要将其转换为线性地址 a. 选择子SEL21h0000000000100 0 01b&#xff0c;他代表的意思是&#xff1a…

Ruoyi框架上传文件

axios资料&#xff1a;axios中文文档|axios中文网 | axios axiosjson 默认情况下&#xff0c;axios将JavaScript对象序列化为JSON。 submit(data) {if (data && this.definitionId) {// 启动流程并将表单数据加入流程变量startProcess(this.definitionId, JSON.string…

ARM 嵌入式端算法加速

OpenCL 嵌入式端算法加速 1 嵌入式端算法加速架构 1.1 OpenMP 1.1.1 平台是否支持 简单理解&#xff0c;我们使用 OpenMP 就可以非常简单地实现多线程有多简单呢&#xff0c;查看是否支持 OpenMP在使用 OpenMP 完成多线程任务时&#xff0c;首先得查看当前编译器是否支持 OpenM…

数据可视化原理-腾讯-3D热力图

在做数据分析类的产品功能设计时&#xff0c;经常用到可视化方式&#xff0c;挖掘数据价值&#xff0c;表达数据的内在规律与特征展示给客户。 可是作为一个产品经理&#xff0c;&#xff08;1&#xff09;如果不能够掌握各类可视化图形的含义&#xff0c;就不知道哪类数据该用…

代码随想录刷题笔记-Day29

1. N皇后 51. N 皇后https://leetcode.cn/problems/n-queens/ 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数…