设计模式之原型模式

原型模式简介

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

原型模式的主要组成

  • Prototype:抽象原型类。声明克隆自身的接口。
  • ConcretePrototype:具体原型类。实现克隆的具体操作。
  • Client:客户类。让一个原型克隆自身,从而获得一个新的对象。

实例模拟

原形类的编写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
public class Person implements Cloneable {

private String head;
private String body;
private String foot;

public String getHead() {
return head;
}

public void setHead(String head) {
this.head = head;
}

public String getBody() {
return body;
}

public void setBody(String body) {
this.body = body;
}

public String getFoot() {
return foot;
}

public void setFoot(String foot) {
this.foot = foot;
}

@Override
public String toString() {
return "Person{" +
"head='" + head + '\'' +
", body='" + body + '\'' +
", foot='" + foot + '\'' +
'}';
}

/**
* 重写clone方法
* @return
* @throws CloneNotSupportedException
*/
@Override
protected Object clone() throws CloneNotSupportedException {
try{
Person person = (Person) super.clone();
return person;
}catch (CloneNotSupportedException e){
e.printStackTrace();
}
return null;
}
}

客户端调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Client {

public static void main(String[] args) throws Exception {
Person person = new Person();
person.setHead("头1");
person.setBody("身体1");
person.setFoot("脚1");
System.out.println(person.toString());

//进行拷贝
Person person2 = (Person)person.clone();
person2.clone();
System.out.println(person2.toString());
}
}

结果如下

因为人有两个脚,此时如果我们把脚的属性改为集合会怎么样

1
private List<String> foot = new ArrayList<>();

再次调用客户端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static void main(String[] args) throws Exception {
//定义第一个人,为他只添加一只左脚
Person person = new Person();
person.setHead("头1");
person.setBody("身体1");
person.getFoot().add("左脚一");
//打印第一个人信息
System.out.println("person1====="+person.toString());

//进行拷贝
Person person2 = (Person)person.clone();
person2.clone();
//拷贝完成之后再为第二个人添加右脚
person2.getFoot().add("右脚一");
//打印第二个人信息
System.out.println("person2====="+person2.toString());

//再次打印第一个人信息
System.out.println("person1====="+person.toString());
}

此时我们发现再拷贝的对象属性发生改变以后原对象也会随之改变,这就是浅克隆,其引用数据类型数据还是还是指向原型对象的,并不会随之克隆

1
2
3
person1=====Person{head='头1', body='身体1', foot=[左脚一]}
person2=====Person{head='头1', body='身体1', foot=[左脚一, 右脚一]}
person1=====Person{head='头1', body='身体1', foot=[左脚一, 右脚一]}
文章目录
  1. 1. 原型模式简介
  2. 2. 原型模式的主要组成
  3. 3. 实例模拟
    1. 3.0.1. 原形类的编写
    2. 3.0.2. 客户端调用
|