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
spring中的原型模式的更多相关文章
- 002-创建型-04-建造者模式(Builder)、JDK1.7源码中的建造者模式、Spring中的建造者模式
一.概述 建造者模式的定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象 ...
- 深度分析:java设计模式中的原型模式,看完就没有说不懂的
前言 原型模式(Prototype模式)是指:用原型实例指定创建对象的种类,并且通过拷贝这些原型,创建新的对象 原型模式是一种创建型设计模式,允许一个对象再创建另外一个可定制的对象,无需知道如何创建的 ...
- 理解javascript中的原型模式
一.为什么要用原型模式. 早期采用工厂模式或构造函数模式的缺点: 1.工厂模式:函数creatPerson根据接受的参数来构建一个包含所有必要信息的person对象,这个函数可以被无数次的调用,工厂 ...
- 浅谈JavaScript中的原型模式
在JavaScript中创建对象由很多种方式,如工厂模式.构造函数模式.原型模式等: <pre name="code" class="html">/ ...
- 在商城系统中使用设计模式----策略模式之在spring中使用策略模式
1.前言: 这是策略模式在spring中的使用,对策略模式不了解对同学可以移步在商城中简单对使用策略模式. 2.问题: 在策略模式中,我们创建表示各种策略的对象和一个行为,随着策略对象改变而改变的 c ...
- Spring中的工厂模式和单例模式
Spring预备知识(适合中小型项目) 作用:集成和管理其他框架 工厂模式: A a = new A( ); 将类所要创建的对象写入工厂,统一进行管理 package com.spring; pu ...
- Spring中的代理模式
代理模式 所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 代理模式是一种 ...
- spring中的工厂模式
spring的bean的创建原理就是框架利用反射创建出实例对象 工厂模式:工厂帮我们创建对象:有一个专门帮我们创建对象的类,我们把这个类叫做工厂类. 例如:Plane plane = PlaneFac ...
- JavaScript中的原型模式
我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法.使用原型对象的好处是可以让所有对象实例共享它 ...
随机推荐
- C# 设置鼠标光标位置
C# 设置鼠标光标位置 using System.Drawing; using System.Runtime.InteropServices; namespace ZB.QueueSys.Common ...
- mongodb索引 复合索引
当我们的查询条件不只有一个时,就需要建立复合索引,比如插入一条{x:1,y:2,z:3}记录,按照我们之前建立的x为1的索引,可是使用x查询,现在想按照x与y的值查询,就需要创建如下的索引 创 ...
- 关于python logging模块读文档的几个心得
1. logger是分层级的,root是所有logger的祖先. 2. root这个logger在执行logging.warning() 等一系列方法和basicConfig()的时候才会被初始化ha ...
- c/c++编译器配置(交叉编译重要参数)、交叉编译动态库与as配置、mk初步
gcc/g++/clang,相当于javac: 了解c/c++编译器的基本使用,能够在后续移植第三方框架进行交叉编译时,清楚的了解应该传递什么参数. clang: clang 是一个C.C++.Obj ...
- Ubuntu死机解决方法汇总
为什么不建议强制关机 如果长按电源按键强制关机,有可能损坏硬件或者丢失数据,甚至导致磁盘坏道! 其实, 大部分时候的死机是假死, 不是真死... 有时候鼠标还能动呢. 还有一个原因: 对于平时忠贞不二 ...
- 前端笔记-css
css(穿着) 1. 第一种<head><style></style></head>中可以写css样式 css选择器 定位到哪个标签的css id选择器 ...
- 大数据之路week05--day01(I/O流阶段一 之File)
众所周知,我们电脑中有许许多多的文件夹和文件,文件的形式也有许多不同的格式,文件夹中也可以新建文件夹的存在,也就是多层的一步一步的嵌套. 我们想要实现I/O操作,就必须知道硬盘上文件的表现形式. 而J ...
- AutoMapper 的简单使用
var config = new MapperConfiguration( cfg => cfg.CreateMap<SYS_Menu, MenuTreeNode>() .ForMe ...
- uni-app之tabBar的自己配置
1.因为产品相关的的权限,需要配置不同的导航,这时候需要自定义导航.分离出来的就是一个小的组件.(tabBar.vue) 此处暂时用的html插入的代码,能粘贴到vue文件即可. <templa ...
- JSP运行原理以及执行过程源码分析
我们在开发JavaWeb的过程中,可能有过这样的疑问,当我们编写jsp页面时,不用引用不用创建就可以使用request.session.application对象,当使用浏览器访问JSP页面时,查看页 ...