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

news2024/11/25 11:02:43

文章目录

  • 创建型模式
    • 原型
    • 建造者模式
      • 扩展
    • 创建型模式对比

创建型模式

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

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

原型

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
原型模式,是指创建新对象的时候,根据现有的一个原型来创建

结构
1、抽象原型类:规定了具体原型对象必须实现的clone()方法
2、具体原型类
3、访问类

在这里插入图片描述
使用场景

  • 对象的创建非常复杂,可以使用原型模式快捷的创建对象
  • 性能和安全要求比较高

浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型,仍指向原有属性所指向的对象的内存地址
深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址

public class Realizetype implements Cloneable {
    public Realizetype(){
        System.out.println("具体原型对象创建成功");
    }
    @Override
    protected Realizetype clone() throws CloneNotSupportedException {
        System.out.println("具体原型对象复制成功");
        return (Realizetype) super.clone();
    }
}

public class Realizetype implements Cloneable {
    public Realizetype(){
        System.out.println("具体原型对象创建成功");
    }
    @Override
    protected Realizetype clone() throws CloneNotSupportedException {
        System.out.println("具体原型对象复制成功");
        return (Realizetype) super.clone();
    }
}

建造者模式

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示

分离了部件的构造和装配,从而可以构造出复杂的对象。

适用于某个对象的构建过程复杂的情况

结构
1、抽象建造者类
2、具体建造者类
3、产品类
4、指挥者类

在这里插入图片描述

优点:

  • 建造者模式封装性很好。
  • 客户不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象
  • 可以更加精细地控制产品的创建过程。
  • 更容易扩展。有新的的需要,通过实现一个新的建造者类就可以完成。

缺点:所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,不适合使用建造者模式

使用场景:

  • 创建的对象复杂,由多个部件构成,各部件面临着复杂的变化,但构件间的建造顺序是稳定的
  • 创建复杂对象的算法独立于该对象的组成部分以及它们的装配方式,即产品的构建过程和最终的表示是独立的

扩展

在开发中常用的使用方式,就是当一个类构造器需要传入很多参数时,如果创建这个类的实例,代码的可读性会非常差,而且很容易引入错误,此时就可以利用建造者模式进行重构

重构前:

public class Phone {
private String cpu;
private String screen;
private String memory;
private String mainboard;
public Phone(String cpu, String screen, String memory, String
mainboard) {
this.cpu = cpu;
this.screen = screen;
this.memory = memory;
this.mainboard = mainboard;
}
public String getCpu() {
return cpu;
}
public void setCpu(String cpu) {
this.cpu = cpu;
}
public String getScreen() {
return screen;
}
public void setScreen(String screen) {
this.screen = screen;
}
public String getMemory() {
return memory;
}
public void setMemory(String memory) {
this.memory = memory;
}
public String getMainboard() {
return mainboard;
}
public void setMainboard(String mainboard) {
this.mainboard = mainboard;
}
@Override
public String toString() {
return "Phone{" +
"cpu='" + cpu + '\'' +
", screen='" + screen + '\'' +
", memory='" + memory + '\'' +
", mainboard='" + mainboard + '\'' +
'}';
}
}
public class Client {
public static void main(String[] args) {
//构建Phone对象
Phone phone = new Phone("intel","三星屏幕","金士顿","华硕");
System.out.println(phone);
}
}

重构后:

public class Phone {
    private String cpu;
    private String screen;
    private String memory;
    private String mainboard;

    private Phone(Builder builder) {
        cpu=builder.cpu;
        screen=builder.screen;
        memory=builder.memory;
        mainboard=builder.mainboard;
    }

    public static final class Builder{
        private String cpu;
        private String screen;
        private String memory;
        private String mainboard;

        public Builder(){}

        public Builder cpu(String val){
            cpu=val;
            return this;
        }

        public Builder mainboard(String val){
            mainboard=val;
            return this;
        }

        public Builder screen(String val){
            screen=val;
            return this;
        }

        public Builder memory(String val){
            memory=val;
            return this;
        }

        public Phone build(){
            return new Phone(this);
        }
    }

    @Override
    public String toString() {
        return "Phone{" +
                "cpu='" + cpu + '\'' +
                ", screen='" + screen + '\'' +
                ", memory='" + memory + '\'' +
                ", mainboard='" + mainboard + '\'' +
                '}';
    }
}
public class client {
    public static void main(String[] args) {
        Phone phone=new Phone.Builder()
                .cpu("cc")
                .mainboard("mainboard")
                .build();
        System.out.println(phone.toString());
    }
}

创建型模式对比

工厂方法模式vs建造者模式
工厂方法模式注重整体对象的创建方式,而建造者模式注重的是部件构造过程,意在通过一步一步地精确构造创建出一个复杂的对象

抽象工厂模式vs建造者模式
抽象工厂模式实现对产品家族的创建,一个产品家族是一系列产品,具有不同分类维度产品组合,采用抽象工厂模式不需要关系构建过程,只关心什么产品由什么工厂生产即可

建造者模式要求按照指定的蓝图建造产品,主要目的是通过组装零配件而产生一个新产品

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

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

相关文章

Factory Method工厂模式(对象创建)

Factory Method(对象创建) 链接:工厂模式实例代码 解析 目的 在软件系统中,经常面临着创建对象的工作;由于需求的变化,需要创建的对象的具体类型经常变化。 如何应对这种变化?如何绕过常规的…

什么是工厂方法模式,工厂方法模式解决了什么问题?

工厂方法模式是一种创建型设计模式,它定义了一个用于创建对象的接口,但将实际的实例化过程延迟到子类中。这样,客户端代码在不同的子类中实例化具体对象,而不是直接实例化具体类。工厂方法模式允许一个类的实例化延迟到其子类&…

词表示:语言与计算的桥梁

目录 前言1 什么是词表示2 独热表示3 上下文表示4 分布式表示结语 前言 在自然语言处理领域,词语的表示是一个基本挑战。将词语转换为计算机可以理解的符号,衡量词语之间的相似度,捕捉它们之间复杂的关系,是使机器能够理解和处理…

RTC实时时钟

简介 RTC时钟是一个独立的定时器,可以在后备电源不掉电的情况下一直运行。在对应的软件配置下一般可以做时钟日历功能。   RTC模块和时钟配置系统(RCC_BDCR寄存器)是在后备区域,即使系统复位或者待机唤醒后RTC的设置和时间都维持…

图片格式 WebP、JPEG、PNG、SVG 及转换

文章目录 图片格式 WebP、JPEG、PNG、SVG 及转换1. 图片格式1.1 WebP1.2 JPEG1.3 PNG1.4 SVG1.5 ... 2. 格式转换2.1 Python 批量转 WebP2.2 在线转换工具2.2.1 Shutterstock2.2.2 PicWish2.2.3 MyEdit2.2.4 Freeconvert2.2.5 iLoveIMG Reference 图片格式 WebP、JPEG、PNG、SV…

WPF+Halcon 培训项目实战(8):WPF+Halcon初次开发

前言 为了更好地去学习WPFHalcon,我决定去报个班学一下。原因无非是想换个工作。相关的教学视频来源于下方的Up主的提供的教程。这里只做笔记分享,想要源码或者教学视频可以和他联系一下。 相关链接 微软系列技术教程 WPF 年度公益课程 Halcon开发 CSD…

MySQL数据库性能优化中常用的方法是什么?

MySQL是目前广泛使用的关系型数据库系统,随着数据量的不断增加和业务需求的提升,MySQL数据库性能优化已经成为开发人员和DBA必须面对的一个重要问题。 查询语句是MySQL数据库中最常用的操作之一,也是造成性能问题的主要原因之一。以下是一些常…

SpringMVC之视图和RESTful

学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。各位小伙伴,如果您: 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持,想组团高效学习… 想写博客但无从下手,急需…

CSI多普勒效应

CSI多普勒效应 一、定义二、应用三、计算方法1方法2STFT和DFT间的区别 一、定义 多普勒频移是指由于运动引起的信号频率的变化。当信号源相对于接收器运动时,由于多普勒效应,信号的频率会发生改变。多普勒频移可以通过以下公式表示: 二、应…

4.16 构建onnx结构模型-And

前言 构建onnx方式通常有两种: 1、通过代码转换成onnx结构,比如pytorch —> onnx 2、通过onnx 自定义结点,图,生成onnx结构 本文主要是简单学习和使用两种不同onnx结构, 下面以 And 结点进行分析 方式 方法一&…

轻松记录、修改收支,让财务一目了然!

收支明细管理是每位个人或企业都必须面对的财务任务,但如何准确记录并修改收支明细却常常让人感到困扰。为了帮助大家更好地管理财务,让你轻松掌握记录、修改收支的技巧,让财务状况一目了然!方法如下: 第一步&#xf…

线上隐私保护的未来:分布式身份DID的潜力

在日益数字化的世界中,人们的生活越来越多地依赖于互联网,数字身份也因而变得越来越重要。根据法律规定,互联网应用需要确认用户的真实身份才能提供各种服务,而用户则希望在进行身份认证的同时能够尽量保护他们的个人隐私&#xf…

云手机快速发展的原因

云手机之所以迅速崛起,根本原因在于5G技术的广泛应用以及音视频技术的不断发展,这些因素共同推动了云手机的使用体验取得显著提升,引发了越来越多公司对云手机的深入研究。那么,为何云手机成为当前和未来的热门趋势呢?…

Linux管理LVM逻辑卷

目录 一、LVM逻辑卷介绍 1. 概述 2. LVM基本术语 2.1 PV(Physical Volume,物理卷) 2.2 VG (Volume Group,卷组) 2.3 LV (Logical Volume,逻辑卷) 3. 常用的磁盘命令 4. 查看系统信息的命…

创建您的第一个记忆卡片游戏

大家好!今天,我们将一起探索如何用HTML、CSS和JavaScript创建一个有趣的记忆卡片游戏。我们的游戏规则很简单:用户需要找到一对一样的卡片。如果你是编程新手,不用担心,我会逐步引导你完成这个项目。 正文&#xff1a…

EyouCMSv1.5.1漏洞复现

赞赞网络科技 EyouCMS(易优CMS)是中国赞赞网络科技公司的一套基于ThinkPHP的开源内容管理系统(CMS)。 Eyoucms v1.5.1 及以前版本存在任意用户后台登陆与文件包含漏洞,该漏洞使攻击者可以通过调用api,在前台…

LIUNX进程程序替换

1.什么是程序替换 a.一个程序,只能执行自己的代码 b.如果想要一个程序执行,别的程序的代码呢? 我们就可以创建一个子进程,将这个子进程替换为我们想要执行的程序。 2.样例代码-----execl(接口) 返回值&…

如何信任机器学习模型的预测结果?

在本篇中,我将通过一个例子演示在 MATLAB 如何使用 LIME 进行复杂机器学习模型预测结果的解释。 我使用数据集 carbig(MATLAB 自带的数据集)训练一个回归模型,用于预测汽车的燃油效率。数据集 carbig 是 70 年代到 80 年代生产的…

Python 简易图形界面库easygui 对话框大全(续)

目录 EasyGUI库 主要特点 使用场景 对话框样式 10. 文件打开框 fileopenbox 11. 文件保存框 filesavebox 12. 目录打开框 diropenbox 13. 索引对话框 indexbox 14. 例外报告框 exceptionbox 15. 代码文本框 codebox 16. 密码输入框 passwordbox 17. 多重文本框 mul…

Spring的Bean你了解吗

Bean的配置 Spring容器支持XML(常用)和Properties两种格式的配置文件 Spring中XML配置文件的根元素是,中包含了多个子元素,每个子元素定义了一个Bean,并描述了该Bean如何装配到Spring容器中 元素包含了多个属性以及子元素,常用属性及子元素如下所示 i…