首页 > 其他分享 >设计模式—创建型模式之原型模式

设计模式—创建型模式之原型模式

时间:2023-10-29 20:23:32浏览次数:31  
标签:return Student 模式 原型 private student 设计模式 public name

设计模式—创建型模式之原型模式

原型模式(Prototype Pattern)用于创建重复的对象,同时又能保证性能。

本体给外部提供一个克隆体进行使用。

比如我们做一个SjdwzMybatis,用来操作数据库,从数据库里面查出很多记录,其中很多记录改变很少。每次查数据库,把所有数据都封装一个对象,然后返回。假设有很多线程,来查如下记录:

Student student = new Student("张三","男");

如果每次都创建对象封装并返回,这样系统就会有很多student;这样就会浪费内存。

Student类如下:

public class Student {
    private String name;
    private Integer age;

    public Student() {
        System.out.println("创建了Student对象");
    }
    //省略getter() 、 setter() toString()
}

SjdwzMybatis如下:

public class SjdwzMybatis {

    /**
     * 通过name获取Student
     */
    public Student queryStudent(String name){
        return queryStudentFromDB(name);
    }

    /**
     * 演示从数据库查Student
     */
    private Student queryStudentFromDB(String name) {
        //简单演示,查询到了
        System.out.println("从数据库查询到了:"+name);
        Student student = new Student();
        student.setName(name);
        student.setAge(16);
        return student;
    }
}

测试类:

public class ProtoTypeTest {
    public static void main(String[] args) {
        SjdwzMybatis sjdwzMybatis = new SjdwzMybatis();
        Student stu1 = sjdwzMybatis.queryStudent("zhangsan");
        Student stu2 = sjdwzMybatis.queryStudent("zhangsan");
        Student stu3 = sjdwzMybatis.queryStudent("zhangsan");
        Student stu4 = sjdwzMybatis.queryStudent("zhangsan");
    }
}

这样会有大量具有相同属性的student被外部创建,同时查库次数过多。

我们是否能设计一个缓存,来保存查过的内容,再查相同的记录时,可以很快拿到原来的原型对象呢?

那我们的SjdwzMybatis便变成了如下代码:

public class SjdwzMybatis {
	//缓存
    private Map<String,Student> stuCache = new HashMap<>();

    /**
     * 通过name获取Student
     */
    public Student queryStudent(String name){
        if(stuCache.containsKey(name)){
            return stuCache.get(name);
        }else{
            return queryStudentFromDB(name);
        }
    }

    /**
     * 演示从数据库查Student
     */
    private Student queryStudentFromDB(String name) {
        //简单演示,查询到了
        System.out.println("从数据库查询到了:"+name);
        Student student = new Student();
        student.setName(name);
        student.setAge(16);
        //存入内存
        stuCache.put(name,student);
        return student;
    }
}

但是这是否会有问题呢?

修改属性

如果我们把stu1的属性改了,那么stu2、stu3、stu4的属性也会被改变,这会影响到我们缓存里的数据,造成脏缓存数据;同时我们查出来的内容,并没有提交修改,不能就把原数据给修改掉。

原型模式

我们把Student修改成如下代码,这便是原型模式:

//实现Cloneable接口,这只是一个标记,还需要重写clone()方法
public class Student implements Cloneable{
    private String name;
    private Integer age;

    //重写clone方法
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Student student = new Student();
        student.setName(this.name);
        student.setAge(this.age);
        return student;
    }
}

然后SjdwzMybatis修改为如下代码:

public class SjdwzMybatis {
    //缓存
    private Map<String,Student> stuCache = new HashMap<>();

    /**
     * 通过name获取Student
     */
    public Student queryStudent(String name) throws CloneNotSupportedException {
        if(stuCache.containsKey(name)){
            return (Student) stuCache.get(name).clone();
        }else{
            return queryStudentFromDB(name);
        }
    }

    /**
     * 演示从数据库查Student
     */
    private Student queryStudentFromDB(String name) throws CloneNotSupportedException {
        //简单演示,查询到了
        System.out.println("从数据库查询到了:"+name);
        Student student = new Student();
        student.setName(name);
        student.setAge(16);
        //存入内存
        stuCache.put(name,(Student) student.clone());
        return student;
    }
}

从数据库查出来放入缓存的对象与从缓存取出来的都是clone出来的。

可以看到,我们对stu1修改,并不会影响其他的数据了。

效果

标签:return,Student,模式,原型,private,student,设计模式,public,name
From: https://www.cnblogs.com/nicaicai/p/17796364.html

相关文章

  • 如何将设计模式责任链模式运用到工作当中
    (文章目录)......
  • 【C++】继承 ⑧ ( 继承 + 组合 模式的类对象 构造函数 和 析构函数 调用规则 )
    文章目录一、继承+组合模式的类对象构造函数和析构函数调用规则1、场景说明2、调用规则二、完整代码示例分析1、代码分析2、代码示例一、继承+组合模式的类对象构造函数和析构函数调用规则1、场景说明如果一个类既继承了基类,又在类中维护了一个其它类型的成员......
  • STM32F3系列 ADC采样单端采样模式(基于LL库)
    STM32F3系列ADC单端采样(基于LL库)芯片型号:STM32f303RBT6开发软件:MDK5&CubeMX&VSCode目录目录STM32F3系列ADC单端采样(基于LL库)目录引言1基础知识1.1ADC转换基本流程1.2时钟树1.3关键参数1.3.1位数1.3.2触发信号1.3.3采样时间1.3.4转换时间2CubeMx配置步骤......
  • laravel:维护模式:上线/下线(10.27.0)
    一,相关文档:https://learnku.com/docs/laravel/10.x/configuration/14836#972c4c二,用artisan工具实现上线下线1,下线,进入维护模式[root@imgdignews]#/usr/local/soft/php8.2.5/bin/phpartisandown   INFO  Applicationisnowinmaintenancemode.2,上线,关......
  • Proxy Facade 设计模式运行时的工作原理介绍
    ProxyFacade设计模式是一个强大的工具,它可以帮助我们创建一个简单的代理外观类,以便根据方法和属性的配置来访问系统的各种功能。在这篇文章中,我们将深入探讨ProxyFacade模式的运行时工作原理,并提供一些实际示例来帮助您更好地理解。什么是ProxyFacade设计模式?ProxyFaca......
  • Commands and Queries 设计模式详解
    在Angular应用开发领域,CommandsandQueries设计模式是一个关键的概念,它有助于有效地管理应用程序的状态和与后端的交互。本文将深入探讨这一设计模式的核心要点,并通过实际示例来加以说明。基本概念命令(Commands)命令代表了一项能够改变系统状态的操作,通常通过向后端发起RES......
  • (二)Qt中使用model/view模式
    Qt包含两种模型Qt提供的两个标准模型是QStandardItemModel和QFileSystemModel。QStandardItemModel是一个多用途模型,可用于表示列表、表和树视图所需的各种不同的数据结构。同时还保存了数据项。QFileSystemModel是一个维护目录内容信息的模型。它本身不保存任何数据项,只是表示本地......
  • 设计模式05:状态模式、策略模式、访问者模式、中介者模式
    1.State状态模式 示例代码:packageState13;/***状态模式*意图:允许一个对象在其内部状态改变的时候改变它的行为。对象看起来似乎修改了它的类*适用于:*一个对象的行为决定于它的状态,并且它需要在运行时刻根据状态改变它的行为**/publicclassState......
  • 设计模式03:原型模式、适配器模式、桥接模式、组合模式
    1.Prototype原型模式 代码示例:packagePrototype05;/***原型模式:*意图:用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象*适用于:*当一个系统应该独立于它的产品创建、构成和表示时*当要实例化的类是在运行时刻指定时例如通过动态装......
  • 设计模式04:装饰器模式、享元模式、命令模式、观察者模式
    1.Decorator装饰器模式 示例代码:packageDecorator09;/***装饰器模式*意图:动态的给一个对象添加一些额外的职责。*适用性:*在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责*处理那些可以撤销的职责*/publicclassDecoratorPatt......