spring中的原型模式

大家好,我原本是神剑山庄的铸剑师,名叫小赵,本来干的好好的,后来一时兴起,睡了三少爷的小姨子,与其一直提心吊胆,干脆来个逃之夭夭。

但是,我也要吃饭的呀,工作也得找,神剑山庄去不得,还有断剑山庄、藏剑山庄、荡剑山庄、等等等等大型企业,说不定这次跳槽,能跳出个飞黄腾达!

为了提高我投简历的准确性,我觉得简历要写的多样化,不能全写一模一样,比如说我的期望薪资不能写成一样,因为我希望能够根据目标企业的情况来投递合适薪资的简历,这样中标概率大一点。

 这是我的简历类:

public class Resume {
    private String name;
    private String position;
    private int salary;

    public String getName() {
        return name;
    }

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

    public String getPosition() {
        return position;
    }

    public void setPosition(String position) {
        this.position = position;
    }

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }

    @Override
    public String toString() {
        return "Resume{" +
                "name=‘" + name + ‘\‘‘ +
                ", position=‘" + position + ‘\‘‘ +
                ", salary=" + salary +
                ‘}‘;
    }
}

  现在,我正在熬夜写简历。。。。。

    public static void main(String[] args) {
        Resume resume1 = new Resume();
        resume1.setName("小赵");
        resume1.setPosition("高级铸剑工程师");
        resume1.setSalary(1000);

        Resume resume2 = new Resume();
        resume2.setName("小赵");
        resume2.setPosition("高级铸剑工程师");
        resume2.setSalary(1200);

        Resume resume3 = new Resume();
        resume2.setName("小赵");
        resume3.setPosition("高级铸剑工程师");
        resume3.setSalary(1500);
        //.....
    }

  当我写到20多份的时候,我已经睡着了。。。。。

  唉,找工作难啊。。。。。。

回到顶部

打印机跑起来

  第二天,我去万达广场买了个打印机回来,直接循环打印!

    public static void main(String[] args) {
        int num = 5;
        while (num > 0){
            Resume resume1 = new Resume();
            int salary = (int)(1000+Math.random()*(2000-1000+1));
            resume1.setName("小赵");
            resume1.setPosition("高级铸剑工程师");
            resume1.setSalary(salary);
            System.out.println(resume1.toString());
            num --;
        }
    }

输出:

Resume{name=‘小赵‘, position=‘高级铸剑工程师‘, salary=1389}
Resume{name=‘小赵‘, position=‘高级铸剑工程师‘, salary=1383}
Resume{name=‘小赵‘, position=‘高级铸剑工程师‘, salary=1345}
Resume{name=‘小赵‘, position=‘高级铸剑工程师‘, salary=1446}
Resume{name=‘小赵‘, position=‘高级铸剑工程师‘, salary=1221}

  先试了一下,打印5份简历,感觉没问题。

  有了这个打印机之后,我也接些私活,帮别人打印简历,生意越做越火,一个月后,我工作没找到,但打印机一天到晚倒是没停过。

  到了现在,我的打印机一天到晚要打印一百万张简历,每次打印都要耗电耗内存耗机器寿命,我的打印机已经报废了好几台,并且在不断的购买新的打印机。

  作为一个工程师,我决定要研究一下有没有更好的解决办法。

回到顶部

复印机跑起来

  听说Cloneable接口有个复印机可以用,我决定去试试,效果的好的话就把复印机装到打印机里面去,搞个多功能一体机。

  这是修改后的简历类:

public class Resume implements Cloneable{
    private String name;
    private String position;
    private int salary;

    public String getName() {
        return name;
    }

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

    public String getPosition() {
        return position;
    }

    public void setPosition(String position) {
        this.position = position;
    }

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }

    @Override
    protected Resume clone(){
        Resume resume = null;
        try{
            resume = (Resume) super.clone();
        }catch (CloneNotSupportedException e){
            e.printStackTrace();
        }
        return resume;
    }

    @Override
    public String toString() {
        return "Resume{" +
                "name=‘" + name + ‘\‘‘ +
                ", position=‘" + position + ‘\‘‘ +
                ", salary=" + salary +
                ‘}‘;
    }
}

复印机跑起来:

    public static void main(String[] args) {
        int num = 5;
        Resume resume = new Resume();
        while (num > 0){
            Resume resume1 = resume.clone();
            int salary = (int)(1000+Math.random()*(2000-1000+1));
            resume1.setName("小赵");
            resume1.setPosition("高级铸剑工程师");
            resume1.setSalary(salary);
            System.out.println(resume1.toString());
            num --;
        }
    }

和打印机的效果是一样的,但是这里事实上只打印了一次,然后其他的都是拷贝复印出来的。

  。。。。。。

  多年之后,我才恍然大悟,当初我用复印机复印简历的做法,其实就是设计模式中的原型模式。

回到顶部

原型模式的使用场景

  大体上有两种使用场景

  1.在需要一个类的大量对象的时候,使用原型模式是最佳选择,因为原型模式是在内存中对这个对象进行拷贝,要比直接new这个对象性能要好很多,在这种情况下,需要的对象越多,原型模式体现出的优点越明显。

  2.如果一个对象的初始化需要很多其他对象的数据准备或其他资源的繁琐计算,那么可以使用原型模式。

  3.当需要一个对象的大量公共信息,少量字段进行个性化设置的时候,也可以使用原型模式拷贝出现有对象的副本进行加工处理。

回到顶部

构造函数的问题

  写个程序测一下构造函数:

public class AAA implements Cloneable {
    public AAA() {
        System.out.println("我来了。。");
    }

    @Override
    protected AAA clone(){
        AAA aaa = null;
        try {
            aaa = (AAA) super.clone();
        }catch (CloneNotSupportedException e){
            e.printStackTrace();
        }
        return aaa;
    }
}

    public static void main(String[] args) {
        AAA aaa = new AAA();
        AAA aaa1 = aaa.clone();
    }

输出:

我来了。。

  就输出一次,这里可以证明对象拷贝的时候构造函数是不会执行的,原因在于拷贝是直接在堆中进行,这其实也可以理解,new的时候,JVM要走一趟类加载流程,这个流程非常麻烦,在类加载流程中会调用构造函数,最后生成的对象会放到堆中,而拷贝就是直接拷贝堆中的现成的二进制对象,然后重新一个分配内存块。

回到顶部

浅拷贝

  上个例子展示什么是浅拷贝

  这里新加一个类BBB:

public class BBB{
    private String name;

    public String getName() {
        return name;
    }

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

  AAA类修改为:

public class AAA implements Cloneable {
    private BBB bbb = new BBB();

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

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

    @Override
    protected AAA clone(){
        AAA aaa = null;
        try {
            aaa = (AAA) super.clone();
        }catch (CloneNotSupportedException e){
            e.printStackTrace();
        }
        return aaa;
    }
}

  main方法:

    public static void main(String[] args) {
        AAA aaa = new AAA();
        aaa.setName("张三");
        System.out.println(aaa.getName());

        AAA aaa1 = aaa.clone();
        System.out.println(aaa1.getName());
    }

输出:

张三
张三

  这种情况就是浅拷贝,java只拷贝你指定的对象,至于你指定的对象里面的别的对象,它不拷贝,还是把引用给你,共享变量,这是一种非常不安全的方式,需要特别注意。

  内部的数组和引用对象不会拷贝,其他的原始基本类型和String类型会被拷贝。

  如果要实现深拷贝呢?

  那就只能在AAA的clone方法里把BBB实例化出来了:

    @Override
    protected AAA clone(){
        AAA aaa = null;
        try {
            aaa = (AAA) super.clone();
            aaa.bbb = new BBB();
        }catch (CloneNotSupportedException e){
            e.printStackTrace();
        }
        return aaa;
    }

原文引用:https://www.cnblogs.com/fengyumeng/p/10646487.html

原文地址:https://www.cnblogs.com/pypua/p/11378158.html

时间: 2024-10-12 17:57:38

spring中的原型模式的相关文章

浅谈JavaScript中的原型模式

在JavaScript中创建对象由很多种方式,如工厂模式.构造函数模式.原型模式等: <pre name="code" class="html">//工厂模式 function createPerson(name,age,job) { var o = new Object; o.name = name; o.age = age; o.job = job; o.sayName = function() { alert(this.name); } retur

理解javascript中的原型模式

一.为什么要用原型模式. 早期采用工厂模式或构造函数模式的缺点:  1.工厂模式:函数creatPerson根据接受的参数来构建一个包含所有必要信息的person对象,这个函数可以被无数次的调用,工厂模式尽管解决了创建多个相似对象的问题,却没有解决对象识别的问题(返回的是自定义的一个对象o,不明确对象o的类型).  2. 构造函数模式:构造函数的调用和其他oo语言一样,用new操作符来构建一个Person的实例:javascript中的构造函数也是函数(所以也可以直接像普通函数那样直接调用方法名

php中的原型模式

一.原型模式定义: php中可使用clone关键词复制已经存在的具体产品.然后具体产品类本身便成为它们生成自己的基础.这就是原型模式.使用该模式我们可能用组合代替继承.这种的转变则促进了代码运行的灵活性,并减少了必须创建的类. 二.本节课的问题: 假设有一块"文明"风格的网络游戏,可在区块组成的格子里操作战斗单元.每个区块分别代表海洋.平原和森林.地形的类别约束了占有单元的移动和格斗能力.我们可以使用TerrainFactory对象来提供Sea.Forest和Plains对象,我们决定

23种设计模式中的原型模式

原型模式:通过复制现有实例来创建新的实例,无须知道相应类的信息. 个人见解:在大量循环时,需要初始化对象,用 原型模式能节省大量的初始化所花费的时间,值得一谈的是浅复制和深复制 浅复制:Object类的clone方法只会拷贝对象中的基本的数据类型,对于数组.容器对象.引用对象等都不会拷贝 代码 在这里我定义了一个学生类Student.java public class Student implements Cloneable { private String name; public Stude

JS中的原型模式

创建一个对象,先来看一段代码: // 例如创建一个 Person 的构造函数, 让人有名字, 可以说话 function Person ( name ) { this.name = name; // 可以说话, 需要有一个方法 this.sayHello = function () { console.log( '你好, 我是 ' + this.name ); }; } var p1 = new Person( '小明' ); var p2 = new Person( '大伟' ); conso

spring中应用模板模式封装ElasticsearchTemplate

1.查询? @Override public <T> FacetedPage<T> queryForPage(SearchQuery query, Class<T> clazz, SearchResultMapper mapper) { SearchResponse response = doSearch(prepareSearch(query, clazz), query); return mapper.mapResults(response, clazz, quer

[工作中的设计模式]原型模式prototype

一.模式解析 提起prototype,最近看多了js相关的内容,第一印象首先是js的原型 var Person=function(name){ this.name=name; } Person.prototype.run=function(){ alert(this.name+" is running"; } 此处的原型是js的特殊定义,在原型上定义的属性和方法所有的类进行共享. 不过设计模式中的原型模式指的是:将已有的对象作为原型,拷贝出一份具有相同属性的新的对象. 模式定义为:原型

Android开发中无处不在的设计模式——原型模式

不知不觉这个系列已经写了三篇了,其实很早之前就想写设计模式了,只不过怕自己误人子弟没有提笔去写.后来在实际开发中,发现设计模式可以让一个开发人员融会贯通所学的知识,为了进一步巩固自己,就写下了这一些列文章.前面介绍了三个模式. Android开发中无处不在的设计模式--单例模式 Android开发中无处不在的设计模式--Builder模式 Android开发中无处不在的设计模式--观察者模式 本篇文章介绍的模式其实很简单,即原型模式,按照惯例,先看定义. 用原型实例指定创建对象的种类,并通过拷贝

spring中策略模式使用

策略模式 工作中经常使用到策略模式+工厂模式,实现一个接口多种实现的灵活调用与后续代码的扩展性.在spring中使用策略模式更为简单,所有的bean均为spring容器管理,只需获取该接口的所有实现类即可. 下面以事件处理功能为例,接收到事件之后,根据事件类型调用不同的实现接口去处理.如需新增事件,只需扩展实现类即可,无需改动之前的代码.这样即做到了功能的隔离,又可防止改动原代码导致的bug. 类图 代码示例 定义接口 public interface IBaseEventService { /