设计模式-创建型

2023-05-16

设计模式类型

1、创建型设计模式:主要解决对象的创建问题,封装复杂的创建过程,解耦对象的创建和使用。
2、创建型包括:单例模式、简单工厂模式、抽象工厂模式、原型模式、构造者模式。

原理与实现
单例模式

1、原理

实现单例模式的关键在于限制类的实例化次数

2、实现
单例模式可以通过私有构造函数和静态方法等方式来实现

2.1 饿汉模式
该实现方式的优点是简单、线程安全,不存在线程安全问题和性能问题。但是,该实现方式的缺点是不能延迟加载,即使在不需要使用 Singleton 实例的情况下也会被创建,这会浪费一定的系统资源。

//饿汉模式
public class Singleton {
    private static Singleton instance = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() {
        return instance;
    }
}

2.2 饱汉模式
该示例中的 Singleton 类是懒汉式单例模式的经典实现方式。该实现方式的缺点是在多线程环境下会存在线程安全问题,可以通过使用 synchronized 关键字或者其他方式来解决。

public class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

在 Spring Framework 中,ApplicationContext 的实现采用了单例模式来管理和缓存 bean 实例。其核心代码在 org.springframework.context.support.AbstractApplicationContext 类中。

工厂模式

1、原理

用来创建不同但类型相关的对象,由不同的参数决定创建的对象实例。将对象的创建和使用分离,由工厂负责创建对象并返回,创建即抽象

2、不同
将工厂模式和其他创建型模式进行比较。工厂模式和抽象工厂模式、建造者模式、原型模式等创建型模式都有相似之处,但是它们的关注点不同。例如,抽象工厂模式关注创建一组相关的对象,而工厂模式关注创建单个对象。(抽象对象-具体对象,抽象工厂-具体工厂)

3、实现

//抽象对象
public interface IRuleConfigParser {
    void parser();
}
//具体对象
public class JsonRuleConfigParser implements IRuleConfigParser {
    @Override
    public void parser() {
        System.out.println("JsonRuleConfigParser");
    }
}
//具体对象
public class XmlRuleConfigParser implements IRuleConfigParser {
    @Override
    public void parser() {
        System.out.println("XmlRuleConfigParser");
    }
}

//简单工厂simpleFactory
public static IRuleConfigParser createParser(String configFormat) {
        IRuleConfigParser parser = null;
        if ("json".equalsIgnoreCase(configFormat)) {
            parser = new JsonRuleConfigParser();
        } else if ("xml".equalsIgnoreCase(configFormat)) {
            // parser = new XmlRuleConfigParser();
        } else if ("yaml".equalsIgnoreCase(configFormat)) {
            //parser = new YamlRuleConfigParser();
        } else if ("properties".equalsIgnoreCase(configFormat)) {
            //parser = new PropertiesRuleConfigParser();
        }
        return parser;
    }
//抽象工厂
public interface IGUIFactory {
    Button createbutton();
    TextField createTextField();
}
//具体工厂
public class WindowsFactory implements IGUIFactory {
    public Button createButton() {
        return new WindowsButton();
    }
    public TextField createTextField() {
        return new WindowsTextField();
    }
}
//具体工厂
public class MacFactory implements IGUIFactory {
    public Button createButton() {
        return new MacButton();
    }
    public TextField createTextField() {
        return new MacTextField();
    }
}

//抽象工厂模式
public static void main(String[] args) {
        GUIFactory factory = new WindowsFactory();
        Button button = factory.createButton();
        TextField textField = factory.createTextField();
        // use button, textField

        factory = new MacFactory();
        button = factory.createButton();
        textField = factory.createTextField();
        window = factory.createWindow();
        // use button, textField
    }

4、Spring Framework 中使用了工厂模式的地方比较多,下面列举几个主要的应用:

4.1 BeanFactory 和 ApplicationContext 接口是 Spring 中最常用的工厂模式的实现。这些接口的实现类负责创建和管理 Spring 容器中的 bean 实例,并在需要时将其提供给其他组件使用。

4.2 Spring AOP 中的切面(Aspect)和增强(Advice)也是通过工厂模式创建的。Spring 使用 AspectJ 和动态代理等技术来实现 AOP,通过配置文件或注解等方式来声明切面和增强,Spring 根据声明的信息创建相应的对象。

4.3 Spring MVC 中的处理器映射器(HandlerMapping)也是通过工厂模式实现的。处理器映射器负责将请求映射到相应的处理器上,Spring 中提供了多种处理器映射器,包括注解处理器映射器、路径匹配处理器映射器等,通过工厂模式来创建对应的处理器映射器对象。

4.4 Spring Security 中的认证管理器(AuthenticationManager)也是通过工厂模式创建的。Spring Security 提供了多种认证管理器的实现,包括基于内存、数据库、LDAP 等方式,通过工厂模式来创建相应的认证管理器对象。

综上所述,Spring Framework 中使用了工厂模式的地方比较多,这也体现了工厂模式在软件设计中的重要性和灵活性。

原型模式

1、原理

创建较大的对象,或者对已有对象进行复制,以节省创建时间。原型模式关注如何复制对象,复制即创建。

2、不同
将原型模式和其他创建型模式进行比较。原型模式和工厂模式、抽象工厂模式、建造者模式等创建型模式都有相似之处,但是它们的关注点不同。例如,工厂模式关注如何创建对象,而原型模式关注如何复制对象。

3、实现

public class Prototype implements Cloneable {
    private String name;

    public Prototype(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }


    @Override
    public Prototype clone() {
        try {
            Prototype clone = (Prototype) super.clone();
            clone.setName("sss");
            // TODO: 复制此处的可变状态,这样此克隆就不能更改初始克隆的内部项
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(this);
            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis);
            ois.readObject();
            return clone;
        } catch (CloneNotSupportedException | IOException | ClassNotFoundException e) {
            throw new AssertionError();
        }
    }
}
public class PrototypeDemo {
    public static void main(String[] args) {
        Prototype prototype = new Prototype("fly");
        Prototype clone = prototype.clone();
        System.out.println(prototype.getName());
        System.out.println(clone.getName());
        clone.setName("xxx");
        System.out.println(clone.getName());
    }
}

3、应用场景

原型模式的核心就是对象的克隆,如Spring Framework 中的使用场景有

3.1 Bean 的作用域
Spring Framework 中的 Bean 可以有多种作用域,包括单例(Singleton)、原型(Prototype)、会话(Session)、请求(Request)等。其中,原型作用域就是使用原型模式实现的。当 Bean 的作用域为原型时,每次获取 Bean 时都会创建一个新的实例,避免了多个对象之间共享状态的问题。

3.2 Web 请求参数绑定
Spring Framework 中的 Web MVC 模块提供了请求参数绑定的功能。在处理请求时,Spring Framework 会根据请求参数自动创建一个实体对象,并将请求参数绑定到该对象的属性上。如果该实体对象是原型作用域的 Bean,那么每次请求都会创建一个新的实例,从而避免了多个请求之间共享状态的问题。

构造者模式

1、原理

用来创建复杂的对象,通过不通过的可选参数,创建不同的对象

2、实现

public class User {
    private final String firstName;
    private final String lastName;
    private final int age;
    private final String address;
    private final String phoneNumber;

    private User(UserBuilder builder) {
        this.firstName = builder.firstName;
        this.lastName = builder.lastName;
        this.age = builder.age;
        this.address = builder.address;
        this.phoneNumber = builder.phoneNumber;
    }

    // Getters and setters

    public static class UserBuilder {
        private String firstName;
        private String lastName;
        private int age;
        private String address;
        private String phoneNumber;

        public UserBuilder setFirstName(String firstName) {
            this.firstName = firstName;
            return this;
        }

        public UserBuilder setLastName(String lastName) {
            this.lastName = lastName;
            return this;
        }

        public UserBuilder setAge(int age) {
            this.age = age;
            return this;
        }

        public UserBuilder setAddress(String address) {
            this.address = address;
            return this;
        }

        public UserBuilder setPhoneNumber(String phoneNumber) {
            this.phoneNumber = phoneNumber;
            return this;
        }

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

设计模式-创建型 的相关文章

  • matlab画圆(及其他常用图形)

    画图 1 matlab画圆 xff08 1 xff09 代码 xff1a x 61 y 61 r 61 1 for i 61 1 100 x i 61 r cos i 2 pi 100 y i 61 r sin i 2 pi 100 plo
  • CircuitPython入门贴

    前言 以前一直玩arduino的 xff0c 但是恼火于每次写完代码 xff0c 都要编译并烧录到MCU上 xff0c 刚开始的blink例程类的小代码还好 xff0c 起码十几秒钟就能烧录成功 xff0c 但是后来随着程序代码量的增加 x
  • Ready! Use 192.168.191.2 to access clientGuru Meditation Error: Core 1 panic‘ed (LoadProhibited).

    问题描述 在用esp32通过wifi和ros主机进行话题通信的过程中 xff0c 串口一直打印如下信息 xff1a Connecting to Zhitong Ready Use 192 168 191 2 to access client
  • Kolla环境部署命令

    注 xff1a 此博客皆为经验所得 xff0c 如有雷同 xff0c 纯属巧合 xff01 1 根据需要 xff0c 配置 etc kolla global yml xff0c 可选择需要部署的容器 xff1b 2 在 etc kolla
  • Baize_ServoDriver_esp32(ROS+Arduino驱动舵机机械臂,通过串口或WiFi话题通信)(数字孪生:虚拟和现实同步)

    介绍 硬件平台 控制板 xff1a Baize ServoDriver esp32 舵机机械臂 xff1a 通过Baize ServoDriver esp32这块舵机驱动板 xff0c 我们来驱动我们的机器人 首先 xff0c 我们通过串口
  • VMware Workstation 17 Player安装Ubuntu22.04

    ps xff1a 部分内容来自于网络整合 首先去官网下载https www vmware com products workstation player html 点击DOWNLOAD FOR FREE 点击GO TO DOWNLOADS
  • opencv运行出现错误ffmpeg

    调试opencv程序 xff0c 运行时出现 xff1a Error opening file build opencv modules videoio src cap ffmpeg impl hpp 578 网络查询 xff0c 原因 x
  • 美团2014校招笔试题第二题答案分析

    今天在论坛里看到一网友贴出的美团2014校招笔试题 xff0c 其中第二题个人觉得答案应该为7次 xff0c 这里做了一个分析 xff0c 欢迎大家指出其中的纰漏 题目 xff1a 有25匹马 xff0c 每次比赛只能有5匹马参加 xff0
  • ssh连接不上

    之前执行ssh ip命令一直ok 最近换环境了 xff0c 执行ssh ip命令 xff0c 登录不了 xff0c 卡住 man一下 xff0c 知道有个 v的用法 xff1a v Verbose mode Causes ssh to pr
  • 怎么把ubuntu系统从英文修改为中文界面

    Ubuntu系统默认安装的语言是英文 xff0c 有些小伙伴使用起来可能觉得不是很方便 xff0c ubuntu是支持中文界面的 xff0c 修改方法也很简单 xff0c 下面就来看看详细的操作 1 更改语言之前首先确保你的虚拟机能够上网
  • 浅谈一次函数的斜率

    以下是一次函数的基本形式 请证明 本函数的斜率为 我们先来看斜率 我们就以函数为例 这个函数的图像是个直线 是吗 没错 所以如何求一个函数的斜率 设高为 底为 所以斜率就是 看到这个式子是不是感到和微分有关系 没错 微分的定义就是求切线函数
  • 华为 5680 OLT native vlan配置方式

    分为两部分 xff1a 1 配置给ONU端口 2 配置给OLT端口 1 在ONU 端口生效 ont port native vlan profile mode 命令功能 此命令用于配置ONT端口的缺省VLAN 当ONT的Native VLA
  • taskset 设置进程的CPU亲和性

    命令行形式 taskset options mask command arg taskset options p mask pid PARAMETER mask cpu亲和性 当没有 c选项时 其值前无论有没有0x标记都是16进制的 当有
  • 关于win7安装nvm和npm遇到的坑

    nvm到官网 xff08 https github com coreybutler nvm windows releases xff09 下载后 xff0c 直接安装 xff0c 可选择安装路径和nodejs的路径 安装完nvm后win7系
  • Highcharts的学习

    简介 xff1a Highcharts 是一个用纯 JavaScript 编写的一个图表库 xff0c 能够很简单便捷的在 Web 网站或是 Web 应用程序添加有交互性的图表 xff0c 并且 免费 提供给个人学习 个人网站和非商业用途使
  • 侠客精神 与 程序员的梦想

    侠客精神 与 程序员的梦想 我高考的那年是2013年 xff0c 也就是说你们高考完 xff0c 我也快要毕业了 促使我写这篇文章不单单是CSDN的 款款相待 xff0c 也是打算对自己的大学生活做一总结和对未来的人生做一规划 先说高考 x
  • 人脸识别之SphereFace

    2017的一篇cvpr xff0c SphereFace Deep Hypersphere Embedding for Face Recognition xff0c 继centerloss之后又一大作 文章主要提出了归一化权值 xff08
  • LovaszSoftmax

    论文 The Lovasz Softmax loss A tractable surrogate for the optimization of the intersection over union measure in neural n
  • ROS::ubuntu18.04 sudo: rosdep:找不到命令

    ubuntu18 04按照wiki上安装步骤执行sudo rosdep init是出现 sudo rosdep xff1a 找不到命令 原因 xff1a python rosdep这个包没有装 解决办法 xff1a 安装python ros
  • LCD12864液晶显示屏工作原理是什么呢?

    LCD12864液晶显示屏应用的非常广泛 xff0c 比如美容仪 xff0c 温度计 xff0c 保温杯 xff0c 汽车仪表等行业领域 xff0c 本文重点是由深圳兴宇合电子技术人员为大家讲解LCD12864液晶显示屏工作原理 xff0c

随机推荐