【设计模式】创建型设计模式

news2024/11/16 17:40:20

创建型设计模式

文章目录

  • 创建型设计模式
    • 一、概述
    • 二、单例模式
    • 三、工厂模式
      • 3.1 简单工厂模式(静态工厂模式)
      • 3.2 工厂方法模式
      • 3.3 抽象工厂模式
      • 3.3 工厂模式小结
    • 四、原型模式
    • 五、建造者模式

一、概述

这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。

  • 单例模式(Singleton Pattern)
  • 工厂模式(Factory Pattern)
  • 抽象工厂模式(Abstract Factory Pattern)
  • 原型模式(Prototype Pattern)
  • 建造者模式(Builder Pattern)

二、单例模式

所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,让某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(静态方法)。

使用场景:需要频繁的进行创建和销毁的对象、创建对象时耗时过多或耗费资源过多(即:重量级对象),但又经常用到的对象、工具类对象、频繁访问数据库或文件的对象(比如数据源session 工厂等);Spring 默认注入对象都是单例模式的。

单例模式有多种实现方式,这里提供三种实现方式:

实现的选择:一般可用饿汉式,涉及反序列化用枚举,要求懒加载用静态内部类

  1. 饿汉式:无懒加载效果,缺点:无懒加载,无法防止反序列化
public class Singleton {
	private final static Singleton INSTANCE = new Singleton();
	private Singleton (){}
	public static Singleton getInstance() {
		return INSTANCE;
	}
}
  1. 枚举实现:确保了单例,且能防止反序列化,缺点:无法懒加载
public enum SingletonEnum {
	INSTANCE;
	public void func() {
		System.out.println("只能通过INSTANCE枚举执行我");
	}
}
  1. 静态内部类:确保多线程下也能保持单例懒加载,缺点:无法防止反序列化创建对象
public class Singleton {
	private Singleton() {}

	private static class SingletonHolder {
		private final static Singleton INSTANCE = new Singleton();
	}

	public static Singleton getInstance() {
		return SingletonHolder.INSTANCE;
	}
}

三、工厂模式

在工厂模式中,在创建对象时不会对调用方暴露创建逻辑,而是通过使用一个共同的接口来指向新创建的对象。

3.1 简单工厂模式(静态工厂模式)

看一个披萨项目:要便于披萨种类的扩展,要便于维护。

  1. 披萨的种类很多(比如 GreekPizza、CheesePizza 等)
  2. 披萨的制作有 prepare,bake, cut, box
  3. 完成披萨店订购功能PizzaOrder

传统方式:

在这里插入图片描述

	public void orderPizza(String type) {
		Pizza pizza = null;
		if ("greek".equals(type)) {
			pizza = new GreekPizza();
		} else if ("cheese".equals(type)) {
			pizza = new CheesePizza();
		} else if ("paper".equals(type)) {
			pizza = new PepperPizza();
		} else {
			throw new RuntimeException("No such pizza!");
		}
		pizza.prepare();
		pizza.bake();
		pizza.cut();
		pizza.box();
	}

上面设计违反了开闭原则,当需要增加一个披萨种类时,调用端也必须修改代码增加判断逻辑。用简单工厂模式实现,则可以将调用方与披萨接口的实现解耦,代码如下,此时增加品种,调用方也无需修改代码。

public class PizzaFactory {
	public static Pizza getPizza(String type) {
		Pizza pizza = null;
		if ("greek".equals(type)) {
			pizza = new GreekPizza();
		} else if ("cheese".equals(type)) {
			pizza = new CheesePizza();
		} else if ("paper".equals(type)) {
			pizza = new PepperPizza();
		} else {
			throw new RuntimeException("No such pizza!");
		}
		return pizza;
	}
}
	public void orderPizza(String type) {
		Pizza pizza = PizzaFactory.getPizza(type);
		pizza.prepare();
		pizza.bake();
		pizza.cut();
		pizza.box();
	}

3.2 工厂方法模式

披萨项目新的需求:客户在点披萨时,可以点不同口味的披萨,比如 北京的奶酪 pizza、北京的胡椒 pizza 或者是伦敦的奶酪 pizza、伦敦没有胡椒 pizza。

传统方式:将工厂分为北京的和伦敦的,分别生产不同口味的披萨

工厂方法模式:在上个工厂类中,新增两个方法,分别代表北京的披萨和伦敦的披萨,对应方法中再创建不同口味的实现类,这种方式即工厂方法模式。

3.3 抽象工厂模式

模式如其名,抽象工厂即超级工厂,用来进行统一工厂的创建,将分类进一步解耦。

在这里插入图片描述

3.3 工厂模式小结

注意事项:作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。

四、原型模式

原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。需要克隆一个对象时,尽量不要创建新的对象,然后一个个设置值。

  1. Java中可以通过实现Cloneable接口,复写clone方法调用父类Object中的clone方法实现,注意:这种方式对于该类中引用数据类型会进行浅拷贝
  2. 通过序列化与反序列化的方式深拷贝克隆原型对象

在这里插入图片描述

原理结构图说明

  1. Prototype : 原型类,声明一个克隆自己的接口
  2. ConcretePrototype: 具体的原型类, 实现一个克隆自己的操作
  3. Client: 让一个原型对象克隆自己,从而创建一个新的对象(属性一样)

五、建造者模式

建造者模式(Builder Pattern) 又叫生成器模式,是一种对象构建模式。它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象。

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

主要解决在软件系统中,有时候面临着 “一个复杂对象” 的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。

在这里插入图片描述

原理图中,创建过程由 Director 指定,也就是构建 Builder 的整体流程被抽象出来了,当需要根据情况,先执行 C 再执行 B时,只需要更改 Director 中的执行顺序即可。

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

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

相关文章

Java入门篇 之 抽象类接口

本篇碎碎念:个人认为压力是一种前进的动力,但是不要有太多压力,不然会使心情烦躁,会控制不住自己的情绪,会在一个临界值爆发,一旦爆发,将迟迟不能消散 今日份励志文案: 努力的背后必有加倍的赏赐…

用cmd看星球大战大电影,c++版本全集星球大战,超长多细节

用cmd看星球大战 最近发现了一个有趣的指令。 是不是感觉很insteresting呢 教程 进入控制面板,点击系统与安全 然后,进入以后,点击启用或关闭 Windows 功能 启用Telnet Client并点击确定 用快捷键winr打开我们的cmd 输入指令 telnet towe…

使用百度翻译API或腾讯翻译API做一个小翻译工具

前言 书到用时方恨少,只能临时抱佛脚。英文pdf看不懂,压根看不懂。正好有百度翻译API和腾讯翻译API,就利用两个API自己写一个简单的翻译工具,充分利用资源,用的也放心。 前期准备 关键肯定是两大厂的翻译API&#x…

Transformer笔记

Transformer encoder-decoder架构 Encoder:将输入序列转换为一个连续向量空间中的表示。Encoder通常是一个循环神经网络(RNN)或者卷积神经网络(CNN),通过对输入序列中的每个元素进行编码,得到…

spass-二元变量相关分析

基础概念 计算相关系数r&#xff1a;利用样本数据计算样本相关系数&#xff0c;样本相关系数反映了两变量间线性相关程度的强弱。相关系数的取值范围界于-1与1之间&#xff0c;即-1≤r≤1 当0<r ≤ 1&#xff0c;表明变量之间存在正相关关系&#xff1b; 当-1 ≤ r…

pythongui实时闹钟

# codinggbk import tkinter as tk from time import strftime# 创建一个主窗口 root tk.Tk() root.title("实时闹钟")# 设置窗口的大小不可变 root.resizable(False, False)# 设置窗口始终保持在最上层 root.attributes(-topmost, True)# 更新时间的函数 def time(…

038、语义分割

之——介绍与数据集 杂谈 语义分割&#xff0c;语义分割(Semantic Segmentation)方法-CSDN博客&#xff1a; 语义分割是计算机视觉领域的一项重要任务&#xff0c;旨在将图像中的每个像素分配到其对应的语义类别中。与物体检测或图像分类不同&#xff0c;语义分割不仅要识别图像…

linux网络——HTTPS加密原理

目录 一.HTTPS概述 二.概念准备 三.为什么要加密 四.常⻅的加密⽅式 1.对称加密 2.⾮对称加密 五.数据摘要&#xff0c;数字签名 六.HTTPS的加密过程探究 1.方案一——只使用对称加密 2.方案二——只使⽤⾮对称加密 3.方案三——双⽅都使⽤⾮对称加密 4.方案四——⾮…

元素水平垂直居中

方法一&#xff1a;定位transform 方法二&#xff1a;flex布局 方法三&#xff1a;定位margin【需要child 元素自身的宽高】 相关HTML代码&#xff1a; <div class"parent"><div class"child"></div> </div> 方法一&#xff1a…

许多网友可能还不知道,升级到Windows 11其实没那么复杂,只要符合几个条件可以了

如果你的Windows 10电脑可以升级Windows 11,现在怎么办?有几种方法可以免费安装新的操作系统。以下是你的选择。 如果你想升级到Windows 11,你可以随时购买一台已经安装了操作系统的新电脑。然而,如果你目前的Windows 10 PC满足所有必要的升级要求,那么在Windows 11免费的…

AIRLOOK与商汤科技强强联合,打造“实景三维与AI大模型”结合的全新盛宴

实景三维中国建设作为数字中国建设的重要内容之一&#xff0c;是一项涉及多方面技术支撑的综合性工程&#xff0c;同时作为AI技术在其中发挥着至关重要的作用&#xff0c;AI大模型的发展也将进一步推动实景三维建模技术的创新和发展。在此背景下&#xff0c;AIRLOOK与商汤科技携…

AUTODL云服务器使用大致步骤(适合本人版)

(一)在官网上创建一个服务器 (二)远程连接指令&#xff1a; 改为&#xff1a; (三)连接后&#xff0c;可在中进行代码运行 输入一些指令 python ......

Backtrader绘图cerebro.plot报错问题的处理

Backtrader绘图cerebro.plot报错问题的处理 1.问题描述 在jupyter 中使用BackTrader &#xff0c;使用绘图功能时&#xff1a; cerebro.plot() 提示错误&#xff1a;ValueError: Axis limits cannot be NaN or Inf 由于backtrader 要求有7列数据&#xff0c;最后一列openint…

Halcon (5):Halcon Solution Guide I basics 导论解析

文章目录 文章专栏前言文章目录翻译文档的说明 结论 文章专栏 Halcon开发 前言 今天开始看Halcon的官方文档。由于市面上的教学主要是以基础的语法&#xff0c;算子简单介绍为主。所以我还是得看官方的文本。别的不多说了。有道词英语词典&#xff0c;启动。 还有就是今天LOL…

Python基础:错误和异常

在Python中的错误可&#xff08;至少&#xff09;被分为两种&#xff1a;语法错误和 异常&#xff0c;均是指在程序中发生的问题和意外情况。Python提供了异常处理机制&#xff0c;使程序能够更容易地应对这些问题。 1. 语法错误&#xff08;Syntax Error&#xff09; 语法错误…

C++算法入门练习——树的带权路径长度

现有一棵n个结点的树&#xff08;结点编号为从0到n-1&#xff0c;根结点为0号结点&#xff09;&#xff0c;每个结点有各自的权值w。 结点的路径长度是指&#xff0c;从根结点到该结点的边数&#xff1b;结点的带权路径长度是指&#xff0c;结点权值乘以结点的路径长度&#x…

前端必备工具

一、百度Ai功能合集 https://chat.baidu.com/ 二、超级复制 这是一个edge插件&#xff0c;那些禁止复制的文本&#xff0c;用这个插件点一下图标&#xff0c;会把当前网页解除禁止复制。 三、集中工具箱 例如一键抠图&#xff0c;感觉还可以&#xff1a; 四、代码漂亮截图 几…

七、文件包含漏洞

一、文件包含漏洞 解释&#xff1a;文件包含漏洞是一种注入型漏洞&#xff0c;其本质就是输入一段用户能够控制的脚本或者代码&#xff0c;并让服务端执行&#xff1b;其还能够使得服务器上的源代码被读取&#xff0c;在PHP里面我们把可重复使用的函数写入到单个文件中&#x…

三菱PLC 模拟量输出模拟量转换功能块S_RTI(内嵌ST)

模拟量输出模拟量转换功能块S_RTI算法原理和公式介绍请参考下面文章链接: PLC模拟量输出 模拟量转换FC S_RTI-CSDN博客文章浏览阅读5.3k次,点赞2次,收藏11次。1、本文主要展示西门子博途模拟量输出转换的几种方法, 方法1:先展示下自编FC:计算公式如下:intput intput Rea…