原型模式

Posted abking

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了原型模式相关的知识,希望对你有一定的参考价值。

原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。

定义一个Car类(浅拷贝)

 1 package top.bigking.prototype;
 2 
 3 import java.util.Date;
 4 
 5 /**
 6  * @Author ABKing
 7  * @Date 2020/2/11 下午2:53
 8  * 浅拷贝
 9  **/
10 public class Car implements Cloneable {
11     private String name;
12     private Date date;
13 
14     @Override
15     protected Object clone() throws CloneNotSupportedException {
16         return super.clone();
17     }
18 
19     public Car() {
20     }
21 
22     public Car(String name, Date date) {
23         this.name = name;
24         this.date = date;
25     }
26 
27     public String getName() {
28         return name;
29     }
30 
31     public void setName(String name) {
32         this.name = name;
33     }
34 
35     public Date getDate() {
36         return date;
37     }
38 
39     public void setDate(Date date) {
40         this.date = date;
41     }
42 }

定义一个Car2类(深拷贝)

 1 package top.bigking.prototype;
 2 
 3 import java.util.Date;
 4 
 5 /**
 6  * @Author ABKing
 7  * @Date 2020/2/11 下午5:39
 8  * 深拷贝
 9  **/
10 public class Car2 implements Cloneable {
11     private String name;
12     private Date date;
13 
14     @Override
15     protected Object clone() throws CloneNotSupportedException {
16         Object obj = super.clone();
17         Car2 car = (Car2) obj;
18         car.setDate((Date) this.date.clone());
19         return obj;
20     }
21 
22     public Car2() {
23     }
24 
25     public Car2(String name, Date date) {
26         this.name = name;
27         this.date = date;
28     }
29 
30     public String getName() {
31         return name;
32     }
33 
34     public void setName(String name) {
35         this.name = name;
36     }
37 
38     public Date getDate() {
39         return date;
40     }
41 
42     public void setDate(Date date) {
43         this.date = date;
44     }
45 }

测试:

 1 package top.bigking.prototype;
 2 
 3 import org.junit.Test;
 4 
 5 import java.util.Date;
 6 
 7 /**
 8  * @Author ABKing
 9  * @Date 2020/2/11 下午4:40
10  **/
11 public class TestPrototype {
12     //浅拷贝
13     @Test
14     public void testShallowCopy() throws CloneNotSupportedException {
15         Date date = new Date(11314211L);
16         Car car1 = new Car("兰博基尼", date);
17         Car car2 = (Car) car1.clone(); //拷贝
18 
19         System.out.println("第一辆车:" + car1 + car1.getName() + "-----" + car1.getDate());
20         System.out.println("第二辆车:" + car2 + car2.getName() + "-----" + car2.getDate());
21 
22         date.setTime(4444524L);
23 
24         System.out.println("--------修改date后-------");
25 
26         System.out.println("第一辆车:" + car1 + car1.getName() + "-----" + car1.getDate());
27         System.out.println("第二辆车:" + car2 + car2.getName() + "-----" + car2.getDate());
28     }
29     //深拷贝
30     @Test
31     public void testDeepCopy() throws CloneNotSupportedException {
32         Date date = new Date(11314211L);
33         Car2 car1 = new Car2("兰博基尼", date);
34         Car2 car2 = (Car2) car1.clone(); //拷贝
35 
36         System.out.println("第一辆车:" + car1 + car1.getName() + "-----" + car1.getDate());
37         System.out.println("第二辆车:" + car2 + car2.getName() + "-----" + car2.getDate());
38 
39         date.setTime(4444524L);
40 
41         System.out.println("--------修改date后-------");
42 
43         System.out.println("第一辆车:" + car1 + car1.getName() + "-----" + car1.getDate());
44         System.out.println("第二辆车:" + car2 + car2.getName() + "-----" + car2.getDate());
45     }
46 }

运行结果分别为:

1 /usr/local/java/jdk1.8.0_231/bin/java -ea -Didea.test.cyclic.buffer.size=1048576 -javaagent:/usr/local/bin/idea-IU-193.5662.53/lib/idea_rt.jar=37975:/usr/local/bin/idea-IU-193.5662.53/bin -Dfile.encoding=UTF-8 -classpath /usr/local/bin/idea-IU-193.5662.53/lib/idea_rt.jar:/usr/local/bin/idea-IU-193.5662.53/plugins/junit/lib/junit5-rt.jar:/usr/local/bin/idea-IU-193.5662.53/plugins/junit/lib/junit-rt.jar:/usr/local/java/jdk1.8.0_231/jre/lib/charsets.jar:/usr/local/java/jdk1.8.0_231/jre/lib/deploy.jar:/usr/local/java/jdk1.8.0_231/jre/lib/ext/cldrdata.jar:/usr/local/java/jdk1.8.0_231/jre/lib/ext/dnsns.jar:/usr/local/java/jdk1.8.0_231/jre/lib/ext/jaccess.jar:/usr/local/java/jdk1.8.0_231/jre/lib/ext/jfxrt.jar:/usr/local/java/jdk1.8.0_231/jre/lib/ext/localedata.jar:/usr/local/java/jdk1.8.0_231/jre/lib/ext/nashorn.jar:/usr/local/java/jdk1.8.0_231/jre/lib/ext/sunec.jar:/usr/local/java/jdk1.8.0_231/jre/lib/ext/sunjce_provider.jar:/usr/local/java/jdk1.8.0_231/jre/lib/ext/sunpkcs11.jar:/usr/local/java/jdk1.8.0_231/jre/lib/ext/zipfs.jar:/usr/local/java/jdk1.8.0_231/jre/lib/javaws.jar:/usr/local/java/jdk1.8.0_231/jre/lib/jce.jar:/usr/local/java/jdk1.8.0_231/jre/lib/jfr.jar:/usr/local/java/jdk1.8.0_231/jre/lib/jfxswt.jar:/usr/local/java/jdk1.8.0_231/jre/lib/jsse.jar:/usr/local/java/jdk1.8.0_231/jre/lib/management-agent.jar:/usr/local/java/jdk1.8.0_231/jre/lib/plugin.jar:/usr/local/java/jdk1.8.0_231/jre/lib/resources.jar:/usr/local/java/jdk1.8.0_231/jre/lib/rt.jar:/home/king/IdeaProjects/GOF_23/target/test-classes:/home/king/IdeaProjects/GOF_23/target/classes:/home/king/maven/repository/junit/junit/4.10/junit-4.10.jar:/home/king/maven/repository/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 top.bigking.prototype.TestPrototype,testShallowCopy
2 第一辆车:top.bigking.prototype.Car@579bb367兰博基尼-----Thu Jan 01 11:08:34 CST 1970
3 第二辆车:top.bigking.prototype.Car@255316f2兰博基尼-----Thu Jan 01 11:08:34 CST 1970
4 --------修改date后-------
5 第一辆车:top.bigking.prototype.Car@579bb367兰博基尼-----Thu Jan 01 09:14:04 CST 1970
6 第二辆车:top.bigking.prototype.Car@255316f2兰博基尼-----Thu Jan 01 09:14:04 CST 1970
7 
8 Process finished with exit code 0

可以很明显的看到,修改date后,时间并没有发生改变

运行第二个JUnit测试:

1 /usr/local/java/jdk1.8.0_231/bin/java -ea -Didea.test.cyclic.buffer.size=1048576 -javaagent:/usr/local/bin/idea-IU-193.5662.53/lib/idea_rt.jar=36785:/usr/local/bin/idea-IU-193.5662.53/bin -Dfile.encoding=UTF-8 -classpath /usr/local/bin/idea-IU-193.5662.53/lib/idea_rt.jar:/usr/local/bin/idea-IU-193.5662.53/plugins/junit/lib/junit5-rt.jar:/usr/local/bin/idea-IU-193.5662.53/plugins/junit/lib/junit-rt.jar:/usr/local/java/jdk1.8.0_231/jre/lib/charsets.jar:/usr/local/java/jdk1.8.0_231/jre/lib/deploy.jar:/usr/local/java/jdk1.8.0_231/jre/lib/ext/cldrdata.jar:/usr/local/java/jdk1.8.0_231/jre/lib/ext/dnsns.jar:/usr/local/java/jdk1.8.0_231/jre/lib/ext/jaccess.jar:/usr/local/java/jdk1.8.0_231/jre/lib/ext/jfxrt.jar:/usr/local/java/jdk1.8.0_231/jre/lib/ext/localedata.jar:/usr/local/java/jdk1.8.0_231/jre/lib/ext/nashorn.jar:/usr/local/java/jdk1.8.0_231/jre/lib/ext/sunec.jar:/usr/local/java/jdk1.8.0_231/jre/lib/ext/sunjce_provider.jar:/usr/local/java/jdk1.8.0_231/jre/lib/ext/sunpkcs11.jar:/usr/local/java/jdk1.8.0_231/jre/lib/ext/zipfs.jar:/usr/local/java/jdk1.8.0_231/jre/lib/javaws.jar:/usr/local/java/jdk1.8.0_231/jre/lib/jce.jar:/usr/local/java/jdk1.8.0_231/jre/lib/jfr.jar:/usr/local/java/jdk1.8.0_231/jre/lib/jfxswt.jar:/usr/local/java/jdk1.8.0_231/jre/lib/jsse.jar:/usr/local/java/jdk1.8.0_231/jre/lib/management-agent.jar:/usr/local/java/jdk1.8.0_231/jre/lib/plugin.jar:/usr/local/java/jdk1.8.0_231/jre/lib/resources.jar:/usr/local/java/jdk1.8.0_231/jre/lib/rt.jar:/home/king/IdeaProjects/GOF_23/target/test-classes:/home/king/IdeaProjects/GOF_23/target/classes:/home/king/maven/repository/junit/junit/4.10/junit-4.10.jar:/home/king/maven/repository/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 top.bigking.prototype.TestPrototype,testDeepCopy
2 第一辆车:top.bigking.prototype.Car2@579bb367兰博基尼-----Thu Jan 01 11:08:34 CST 1970
3 第二辆车:top.bigking.prototype.Car2@255316f2兰博基尼-----Thu Jan 01 11:08:34 CST 1970
4 --------修改date后-------
5 第一辆车:top.bigking.prototype.Car2@579bb367兰博基尼-----Thu Jan 01 09:14:04 CST 1970
6 第二辆车:top.bigking.prototype.Car2@255316f2兰博基尼-----Thu Jan 01 11:08:34 CST 1970
7 
8 Process finished with exit code 0

可以看到,时间已经发生了变化。

 

以上是关于原型模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式之原型模式(Prototype)详解及代码示例

设计模式课程 设计模式精讲 9-2 原型模式coding

设计模式--原型模式

5.原型模式

设计模式原型模式

csharp 设计模式 - 原型 - 结构代码