Java学习——设计模式——创建型模式1

文章目录

  • 创建型模式
    • 单例
      • 饿汉式
      • 懒汉式
      • 存在的问题
    • 工厂方法
      • 简单工厂模式
      • 工厂方法模式
      • 抽象工厂模式

创建型模式

关注点是如何创建对象,核心思想是要把对象创建和使用相分离,这样两者能相对独立地变换

包括:
1、工厂方法:Factory Method
2、抽象工厂:Abstarct Factory
3、建造者:Builder
4、原型:Prototype
5、单例:Singleton

单例

最简单的设计模式之一,目的是为了保证在一个进程中,某个类有且仅有一个实例。

结构
单例模式主要有以下角色:

  • 单例类。只能创建一个实例的类。
  • 访问类。使用单例类。

分类

  • 饿汉式:类加载就会导致单实例对象被创建
  • 懒汉式:类加载不会导致该单实例对象被创建,而是首次使用该对象时才会创建

饿汉式

1、静态变量方式

/*饿汉式静态变量创建类的对象*/public class Singleton {
//    私有构造方法private Singleton() {}//    成员位置创建该类的对象private static Singleton instance = new Singleton();//    对外提供静态方法获取该对象public static Singleton getInstance(){return instance;}
}

instance对象是随着类的加载而创建的。如果该对象足够大的话,而一直没有使用就会造成内存浪费。

2、静态代码块方式

package DesignPattern.Single.demo2;/*饿汉式静态代码块中创建类的对象*/public class Singleton {
//    私有构造方法private Singleton() {}//    成员位置创建该类的对象private static Singleton instance;static {instance = new Singleton();}//    对外提供静态方法获取该对象public static Singleton getInstance(){return instance;}
}

也存在内存浪费问题

3、枚举方式

枚举类实现单例模式是激励推荐的单例实现模式,因为枚举类型是线程安全的,并且只会装载一次,设计者充分的利用了枚举的这个特性来实现单例模式,枚举的写法非常简单,而且枚举类型是所用单例实现中唯一一种不会被破坏的单例实现模式。

public enum Singleton{INSTANCE;
}

懒汉式

1、线程不安全

/*懒汉式线程不安全*/public class Singleton {
//    私有构造方法private Singleton() {}//    声明Singleton类型的变量instanceprivate static Singleton instance;//    对外提供访问方式public static Singleton getInstance(){
//        判断instance是否为null,如果为null,说明还没有创建Singleton的对象if(instance == null){//如果有两个线程,线程1等待,线程2获取到CPU的执行权,也会进入到该判断instance=new Singleton();}return instance;}
}

2、线程安全

/*懒汉式线程安全*/public class Singleton {
//    私有构造方法private Singleton() {}//    声明Singleton类型的变量instanceprivate static Singleton instance;//    对外提供访问方式public static synchronized Singleton getInstance(){
//        判断instance是否为null,如果为null,说明还没有创建Singleton的对象if(instance == null){instance=new Singleton();}return instance;}
}

3、双重检查锁

/*懒汉式双重检查锁*/public class Singleton {
//    私有构造方法private Singleton() {}//    声明Singleton类型的变量instanceprivate static Singleton instance;//    对外提供访问方式public static Singleton getInstance(){
//        第一次判断,如果instance的值不为null,不需要抢占锁,直接返回对象if(instance == null){synchronized (Singleton.class){
//              第二次判断if(instance==null){instance=new Singleton();}}}return instance;}
}

双重检查锁模式解决了单例、性能、线程安全问题,但在多线程的情况下,可能会出现空指针问题,出现问题的原因是JVM在实例化对象的时候会进行优化和指令重排序操作。

要解决双重检查锁模式带来空指针异常的问题,只需要使用volatile关键字,volatile关键字可以保证可见性和有序性

/*懒汉式双重检查方式*/public class Singleton {
//    私有构造方法private Singleton() {}//    声明Singleton类型的变量instanceprivate static volatile Singleton instance;//    对外提供访问方式public static Singleton getInstance(){
//        第一次判断,如果instance的值不为null,不需要抢占锁,直接返回对象if(instance == null){synchronized (Singleton.class){
//              第二次判断if(instance==null){instance=new Singleton();}}}return instance;}
}

4、静态内部类方式
JVM在加载外部类的过程中,是不会加载静态内部类的,只有内部类的属性/方法被调用时才会被加载,并初始化其静态属性。静态属性由于被static修饰,保证只被实例化一次,并且严格保证实例化顺序

/*懒汉式静态内部类方式*/public class Singleton {
//    私有构造方法private Singleton() {}//  定义一个静态内部类private static class SingletonHolder{
//        在内部类中声明并初始化外部类的对象private static final Singleton INSTANCE = new Singleton();}public static Singleton getInstance(){return SingletonHolder.INSTANCE;}}

存在的问题

单例有可能被破坏,序列化和反射可以在单例中创建多个对象,枚举除外。

工厂方法

简单工厂模式

不是23种设计模式,比较像一种编程习惯

结构
1、抽象产品
2、具体产品
3、具体工厂

原来:
CoffeeStore–匹配咖啡种类
Coffee
AmericanCoffee
LatteCoffee

简单工厂:
CoffeeStore–调用工厂类
SimpleCoffeeFactory–匹配咖啡种类

public class SimpleCoffeeFactory {public Coffee createCoffee(String type) {Coffee coffee = null;if("americano".equals(type)) {coffee = new AmericanoCoffee();} else if("latte".equals(type)) {coffee = new LatteCoffee();}return coffee;}
}

Coffee
AmericanCoffee
LatteCoffee

优点:封装了创建对象的过程,可以通过参数直接获取对象,把对象的创建和业务逻辑层分开,避免修改客户代码,实现新产品直接修改工厂类,不需要在原代码种修改

缺点:增加新产品时还是需要修改工厂类的代码,违背了“开闭原则”

扩展

静态工厂

把工厂类中创建对象的功能定义为静态的

public class SimpleCoffeeFactory {public static Coffee createCoffee(String type) {Coffee coffee = null;if("americano".equals(type)) {coffee = new AmericanoCoffee();} else if("latte".equals(type)) {coffee = new LatteCoffee();}return coffe;}
}

在这里插入图片描述
好处是可以直接通过类名调用

工厂方法模式

定义一个用于创建对象的接口,让子类决定实例化哪一个类。
目的是使创建对象和使用对象分离,并且客户端总是引用抽象工厂和抽象产品。

在这里插入图片描述结构
1、抽象工厂
2、具体工厂
3、抽象产品
4、具体产品

CoffeeFactory<>
CoffeeStore
Coffee
AmericanCoffee
LatteCoffee
AmericanCoffeeFactory
LatteCoffeeFactory

在这里插入图片描述
优点:

  • 用户只需要知道具体工厂的名称就可得到所要的产品,无需知道产品的具体创建过程
  • 系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无需对原工厂进行任何修改

缺点:每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,增加了系统的复杂度

抽象工厂模式

抽象工厂模式是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构

是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生成多个等级的产品

结构
1、抽象工厂
2、具体工厂
3、抽象产品
4、具体产品

在这里插入图片描述如果要加同一个产品族的话,只需要再加一个对应的工厂类即可,不需要修改其他的类。

优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。

缺点:当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。

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

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

相关文章

嵌入式Linux:提升VMware虚拟机运行速度的方法

使用虚拟机运行Linux操作系统通常会比在物理机上直接安装系统的运行效率更低&#xff0c;本篇博文将介绍如何优化虚拟机的设置&#xff0c;进而提升虚拟机性能体验。 第1步&#xff1a;选择VMware菜单&#xff1a;编辑–>首选项–>更新&#xff0c;将”启动时检查产品更新…

ClickHouse基础知识(二):ClickHouse 安装教程

1. 准备工作 1.1 确定防火墙处于关闭状态 1.2 CentOS 取消打开文件数限制 &#xff08;1&#xff09;在 hadoop101 的 /etc/security/limits.conf 文件的末尾加入以下内容 sudo vim /etc/security/limits.conf&#xff08;2&#xff09;在 hadoop101 的/etc/security/limits.…

IntelliJ IDEA使用EasyCode插件根据Mysql表自动生成代码文件(controller、service、dao、mapper.xml等)

一、Intellij安装EasyCode插件&#xff1a; 首先点击 Intellij->Preference->Plugins&#xff0c;然后搜索 EasyCode&#xff0c;点击安装&#xff1a; 二、添加项目 新建spring boot项目, easy-code-demo 这里以easy-code-demo为例 3 连接Mysql 通过 IDEA 上的 Dat…

【Java系列】多线程案例学习——基于阻塞队列实现生产者消费者模型

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【Java系列专栏】【JaveEE学习专栏】 本专栏旨在分享学习JavaEE的一点学习心得&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录…

计算机中找不到vcruntime140.dll无法启动此程序怎么解决?

无法继续执行代码&#xff0c;因为找不到vcruntime140.dll”。那么&#xff0c;vcruntime140.dll是什么文件&#xff1f;它的作用是什么&#xff1f;当它丢失时会对电脑产生什么影响&#xff1f;本文将为您详细介绍vcruntime140.dll文件的相关知识&#xff0c;并提供五种解决vc…

2024年【低压电工】试题及解析及低压电工模拟考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 低压电工试题及解析参考答案及低压电工考试试题解析是安全生产模拟考试一点通题库老师及低压电工操作证已考过的学员汇总&#xff0c;相对有效帮助低压电工模拟考试学员顺利通过考试。 1、【单选题】()仪表可直接用于…

Linux 查看系统类型和版本(内核版本 | 发行版本)

Linux 查看系统类型和版本 首先普及下linux系统的版本内容1. 查看linux系统内核版本2. 查看linux系统发行版本 首先普及下linux系统的版本内容 内核版本和发行版本区别 内核版本就是指 Linux 中最基层的代码&#xff0c;版本号如 Linux version 3.10.0-327.22.2.el7.x86_64发行…

项目经理面试10问

今天我们来说说项目经理专业面试的十条经验总结。如果你认真阅读并思考&#xff0c;相信对在屏幕前的你会有所帮助和启发。 1、请做一下自我介绍 自我介绍很重要。无论面试什么岗位&#xff0c;面试官通常都会问你一个最常见的问题&#xff1a;“请做一下自我介绍。” 在准备…

信号与线性系统翻转课堂笔记15——离散LTI系统模型分析

信号与线性系统翻转课堂笔记15——离散LTI系统模型分析 The Flipped Classroom15 of Signals and Linear Systems 对应教材&#xff1a;《信号与线性系统分析&#xff08;第五版&#xff09;》高等教育出版社&#xff0c;吴大正著 一、要点 &#xff08;1&#xff0c;重点&…

如何为前端编写单元测试?从这篇入门指南开始学习!

前言 对于现在的前端工程&#xff0c;一个标准完整的项目&#xff0c;通常情况单元测试是非常必要的。但很多时候我们只是完成了项目而忽略了项目测试。我认为其中一个很大的原因是很多人对单元测试认知不够&#xff0c;因此我写了这边文章&#xff0c;一方面期望通过这篇文章…

HPM6750开发笔记《第一个helloworld例程》

HPM_SDK的使用&#xff1a; HPM_SDK界面如下图 此处选择所支持的5款evk大家根据自己的板子选 此处选择想看的例程工程 此处可选择生成工程的类型 其中debug工程是在纯RAM中运行的&#xff0c;板子掉电后代码会被删除&#xff0c;用来测试比较合适 其中挂flash的工程有两种其中…

java设计模式学习之【解释器模式】

文章目录 引言解释器模式简介定义与用途实现方式 使用场景优势与劣势在Spring框架中的应用表达式解析示例代码地址 引言 在我们的日常生活中&#xff0c;语言的翻译和理解是沟通的关键。每种语言都有自己的语法规则&#xff0c;而翻译人员和计算机程序需要理解并遵循这些规则来…

【将G2O库使用交叉编译移植到arm平台】

一 准备材料 1.下载好g2o的代码。下载地址&#xff1a;https://github.com/RainerKuemmerle/g2o 如果只是在Ubuntu系统上安装g2o&#xff0c;可以参考代码库中的readme.md。 2.下载suitesparse4.4.6. 选择4.4.6版本是因为我发现ROS系统中使用的是这个版本。即使用sudo apt-get …

【Vulnhub 靶场】【Looz: 1】【简单】【20210802】

1、环境介绍 靶场介绍&#xff1a;https://www.vulnhub.com/entry/looz-1,732/ 靶场下载&#xff1a;https://download.vulnhub.com/looz/Looz.zip 靶场难度&#xff1a;简单 发布日期&#xff1a;2021年08月02日 文件大小&#xff1a;2.1 GB 靶场作者&#xff1a;mhz_cyber &…

c语言:输出范围内的质数|练习题

一、题目 输入一个数n&#xff0c;输出n之内的所有质数 如图&#xff1a; 二、思路分析 1、设置一个数num&#xff0c;从2开始&#xff0c;不断作1操作&#xff0c;作为被除数 2、用一个不断自1的数&#xff0c;除以num&#xff0c;如果num不能被整除&#xff0c;则为质数 3、例…

超分之SRGAN

Photo-Realistic Single Image Super-Resolution Using a Generative Adversarial Network使用生成对抗网络的逼真单图像超分辨率一作&#xff1a;Christian Ledig是Twitter2017年的一篇论文。 文章目录 0. 摘要1. 引言1.1 相关工作1.1.1 介绍了SR技术的发展历程1.1.2 介绍了SR…

算法基础day2

前缀和 #include <iostream> using namespace std; const int N100010; int n,m; int a[N],s[N]; int main() {scanf("%d%d",&n,&m);for(int i1;i<n;i) scanf("%d",&a[i]);for(int i1;i<n;i) s[i]s[i-1]a[i];while(m--){int l,r;s…

模型系列:增益模型Uplift Modeling原理和案例

模型系列&#xff1a;增益模型Uplift Modeling原理和案例 目录 1. 简介1. 第一步2. 指标3. 元学习器 3.1 S-学习器3.2 T-学习器3.3 T-学习器相关模型 简介 Uplift是一种用于用户级别的治疗增量效应估计的预测建模技术。每家公司都希望增加自己的利润&#xff0c;而其中一个…

Python+OpenCV 零基础学习笔记(6):ROI

文章目录 相关链接运行环境前言ROI颜色区域分割颜色通道合并 相关链接 【2022B站最好的OpenCV课程推荐】OpenCV从入门到实战 全套课程 CSDN标题里个括号对应视频的分P OpenCVPython CSDN专栏 Gitee 项目地址 运行环境 Python:3.11.5Anaconda:23.7.4IDE:vscode运行环境&#x…

链表:如何利用“假头,新指针,双指针”解决链表问题

Java学习面试指南&#xff1a;https://javaxiaobear.cn 链表是一种线性数据结构&#xff0c;其中的每个元素实际上是一个单独的对象&#xff0c;而所有对象都通过每个元素中的引用字段链接在一起。 链表是一种物理存储单元上非连续、非顺序的存储结构&#xff0c;其物理结构不能…