Skip to content

Commit 4edcc68

Browse files
committed
增加原型模式的示例代码
1 parent f034bcd commit 4edcc68

File tree

10 files changed

+296
-0
lines changed

10 files changed

+296
-0
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.company.prototype;
2+
3+
public class Client {
4+
public static void main(String[] args) {
5+
// WordDocument originDoc =new WordDocument();
6+
WordDocument2 originDoc = new WordDocument2();
7+
originDoc.setText("这是一篇文档");
8+
originDoc.addImage("图片1");
9+
originDoc.addImage("图片2");
10+
originDoc.addImage("图片3");
11+
originDoc.showDocument();
12+
13+
// WordDocument doc2 = originDoc.clone();
14+
WordDocument2 doc2 = originDoc.clone();
15+
doc2.showDocument();
16+
17+
doc2.setText("这是修改过的文档");
18+
doc2.addImage("哈哈.png");
19+
doc2.showDocument();
20+
21+
originDoc.showDocument();
22+
}
23+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package com.company.prototype;
2+
3+
import java.util.ArrayList;
4+
5+
/**
6+
* 文档类型,代表ConcretePrototype Cloneable代表prototype角色,生命具备clone的能力
7+
*/
8+
public class WordDocument implements Cloneable {
9+
private String text;//文本
10+
private ArrayList<String> images = new ArrayList<>();//图片
11+
12+
public WordDocument() {
13+
System.out.println("--------WordDocument的构造函数--------");
14+
}
15+
16+
public String getText() {
17+
return text;
18+
}
19+
20+
public void setText(String text) {
21+
this.text = text;
22+
}
23+
24+
public ArrayList<String> getImages() {
25+
return images;
26+
}
27+
28+
public void addImage(String image) {
29+
this.images.add(image);
30+
}
31+
32+
@Override
33+
protected WordDocument clone() {
34+
try {
35+
WordDocument wordDocument = (WordDocument) super.clone();//返回新的对象
36+
wordDocument.text = this.text;
37+
wordDocument.images = this.images;
38+
return wordDocument;
39+
} catch (Exception e) {
40+
e.printStackTrace();
41+
}
42+
return null;
43+
}
44+
45+
public void showDocument() {
46+
System.out.println("--------Word Content Start--------");
47+
System.out.println("Text: " + text);
48+
System.out.println("Image lists");
49+
for (String imageName : images) {
50+
System.out.println("Image name: " + imageName);
51+
}
52+
System.out.println("--------Word Content End--------");
53+
}
54+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package com.company.prototype;
2+
3+
import java.util.ArrayList;
4+
5+
/**
6+
* 文档类型,代表ConcretePrototype Cloneable代表prototype角色,生命具备clone的能力
7+
*/
8+
public class WordDocument2 implements Cloneable {
9+
private String text;//文本
10+
private ArrayList<String> images = new ArrayList<>();//图片
11+
12+
public WordDocument2() {
13+
System.out.println("--------WordDocument的构造函数--------");
14+
}
15+
16+
public String getText() {
17+
return text;
18+
}
19+
20+
public void setText(String text) {
21+
this.text = text;
22+
}
23+
24+
public ArrayList<String> getImages() {
25+
return images;
26+
}
27+
28+
public void addImage(String image) {
29+
this.images.add(image);
30+
}
31+
32+
@Override
33+
protected WordDocument2 clone() {
34+
try {
35+
WordDocument2 wordDocument = (WordDocument2) super.clone();//返回新的对象
36+
wordDocument.text = this.text;
37+
// 对对象的引用数据类型,采用clone(),进行深拷贝
38+
wordDocument.images = (ArrayList<String>) this.images.clone();
39+
return wordDocument;
40+
} catch (Exception e) {
41+
e.printStackTrace();
42+
}
43+
return null;
44+
}
45+
46+
public void showDocument() {
47+
System.out.println("--------Word Content Start--------");
48+
System.out.println("Text: " + text);
49+
System.out.println("Image lists");
50+
for (String imageName : images) {
51+
System.out.println("Image name: " + imageName);
52+
}
53+
System.out.println("--------Word Content End--------");
54+
}
55+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.company.prototype.login;
2+
3+
public class Address {
4+
public String city;
5+
public String district;
6+
public String street;
7+
8+
public Address(String city, String district, String street) {
9+
this.city = city;
10+
this.district = district;
11+
this.street = street;
12+
}
13+
14+
@Override
15+
public String toString() {
16+
return "Address{" +
17+
"city='" + city + '\'' +
18+
", district='" + district + '\'' +
19+
", street='" + street + '\'' +
20+
'}';
21+
}
22+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.company.prototype.login;
2+
3+
public interface Login {
4+
void login();
5+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.company.prototype.login;
2+
3+
public class LoginImpl implements Login {
4+
@Override
5+
public void login() {
6+
// 登陆到服务器,获取用户信息
7+
User user = new User();
8+
// 将服务器返回的信息设置给loginUser
9+
user.age = 22;
10+
user.name = "Night";
11+
user.phoneNum = "12685699865";
12+
user.address = new Address("南阳", "西峡", "二郎坪");
13+
14+
// 登陆完成之后将用户信息设置懂啊LoginSession中
15+
LoginSession loginSession = LoginSession.getLoginSession();
16+
loginSession.setLoginUser(user);//因为setLoginSession()为包级私有,外部module无法调用
17+
18+
}
19+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.company.prototype.login;
2+
3+
//登陆session
4+
public class LoginSession {
5+
static LoginSession loginSession = null;
6+
private User loginUser;//当前登陆的用户信息
7+
8+
private LoginSession() {
9+
10+
}
11+
12+
public static LoginSession getLoginSession() {
13+
if (loginSession == null) {
14+
loginSession = new LoginSession();
15+
}
16+
return loginSession;
17+
}
18+
19+
public User getLoginUser() {
20+
// return loginUser;
21+
return loginUser.clone();
22+
}
23+
24+
// 设置已经登陆的用户信息,不对外开放,包级私有
25+
void setLoginUser(User user) {
26+
this.loginUser = user;
27+
}
28+
29+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.company.prototype.login;
2+
3+
4+
//登陆测试类
5+
public class Test {
6+
public static void main(String[] args) {
7+
// User curUser = LoginSession.getLoginSession().getLoginUser();
8+
User curUser = new User();
9+
// 将服务器返回的信息设置给loginUser
10+
curUser.age = 22;
11+
curUser.name = "Night";
12+
curUser.phoneNum = "12685699865";
13+
curUser.address = new Address("南阳", "西峡", "二郎坪");
14+
System.out.println("用户原始的信息:");
15+
System.out.println(curUser);
16+
17+
curUser.address = new Address("南京", "建邺", "油坊桥");
18+
System.out.println("用户现在的信息:");
19+
System.out.println(curUser);
20+
21+
22+
}
23+
24+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.company.prototype.login;
2+
3+
public class User implements Cloneable {
4+
public int age;
5+
public String name;
6+
public String phoneNum;
7+
public Address address;
8+
9+
@Override
10+
public String toString() {
11+
return "User{" +
12+
"age=" + age +
13+
", name='" + name + '\'' +
14+
", phoneNum='" + phoneNum + '\'' +
15+
", address=" + address +
16+
'}';
17+
}
18+
19+
@Override
20+
protected User clone() {
21+
User user = null;
22+
try {
23+
user = (User) super.clone();
24+
} catch (CloneNotSupportedException e) {
25+
e.printStackTrace();
26+
}
27+
return user;
28+
}
29+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
原型模式:
2+
3+
它是一个创建型模式。原型表明该模式应该有一个样板实例。用户从这个样板实例中复制出一个内部属性一直的对象,即克隆。
4+
被复制的对象就是“原型”。
5+
6+
目的:原型模式定义用于创建复杂的或者构造耗时的实例,复制一个已经存在的实例可以使程序运行更加高效
7+
8+
9+
使用场景:
10+
1.类初始化需要消耗很多资源,这个资源包括数据、硬件资源等。通过原型拷贝避免消耗
11+
2.通过new产生一个对象需要非常繁琐的数据准备或者访问权限,原型模式可以避免
12+
3.提供保护性拷贝
13+
14+
注意:通过实现Cloneable接口的原型模式在调用clone函数构造实例时并不一定比通过new操作更快,只有当通过new操作更
15+
耗时或者消耗资源的时候,通过clone方法才能获得效率上的提升。因此使用的时候要做比较
16+
17+
角色介绍:
18+
Client 客户端用户
19+
Prototype 抽象类或者接口 生命具备clone的能力
20+
ConcretePrototype 具体的原型类
21+
22+
注意clone方法并不是Cloneable接口中的,它是一个标识接口,表明这个类是可以拷贝的。而具体的拷贝来自于Object
23+
的clone()。没有生命这个接口的类调用了clone()会报错
24+
25+
通过clone拷贝对象,并不会执行其构造方法
26+
27+
浅拷贝和深拷贝:
28+
浅拷贝:原始类型的字段根据原数据重新构建,引用类型数据直接指向原数据的引用
29+
深拷贝:对于引用类型的数据,拷贝对象的时候,也要采用拷贝的形式。不能是单纯的引用
30+
31+
32+
优点:是在内存中的二进制流的拷贝,要比直接new一个对象性能更好,特别是在一个循环体内需要产生大量对象的时候,
33+
原型模式更能体现其优点
34+
缺点:直接在内存中拷贝,构造函数不执行
35+
36+
安卓中的应用:ArrayList Intent的查找和匹配。注意此处Intent的拷贝用的是new 方法

0 commit comments

Comments
 (0)