版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_40780805/article/details/82972363
原型模式(Prototype Pattern):诶呀,一种灰常简单的模式,就是要求对象实现一个可以“克隆”自身的接口,这样就可以通过复制一个实例对象本身来创建一个新的实例。只要实现了克隆自身的方法,就可以通过这个方法来获取新的对象,而无须再去通过new来创建。
Specify the kinds of objects to create using a prototypical instance,and create new objects by copying this prototype.
用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。
角色:
- 客户(Client):提出创建对象的请求
- 抽象原型(Prototype):给出所有具体原型所需要的借口(如:抽象一个克隆方法)
- 具体原型(Concrete Prototype):被复制的对象,必须实现抽象原型接口
Java中内置了克隆机制,Object类有一个clone()方法,能够实现对象的克隆,因此在java中实现一个类支持克隆只需两步:
- 实现Cloneable接口
- 覆盖Object的clone()方法,完成对象的克隆操作,由于该clone()方法的访问性是protected的,为了使外部可以调用,可以在覆盖的时候将其改为public
注意:(由于clone()方法是protected修饰的,因此需要实现Cloneable接口才能调用,同时需要覆写clone()方法才能调用。)
列子:群发短信,对短信类对象可以采用克隆的方式,原型模式是在内存二进制流的复制,要比new一个对象性能好。
import java.util.ArrayList;
import java.util.List;
public class PrototypeModel {
/**
* 原型模式
*/
//main方法充当客户类
public static void main(String[] args) {
//装载用户数据(实际开发中应该从数据库中获取用户信息)
List<User> userList=new ArrayList<User>();
User user=new User();
User user1;
user1=(User) user.clone();
user1.setName("张三");
user1.setPhone("15678948737");
userList.add(user1);
user1=(User) user.clone();
user1.setName("小明");
user1.setPhone("15698645674");
userList.add(user1);
//调用发送短信
Message mes=new Message("元旦快乐");
sendMessage(userList, mes);
}
//发送短信
public static void sendMessage(List<User> list,Message mes){
Message message;
for(User user: list){
//调用消息对象的克隆方法
message=(Message) mes.clone();
message.setPhone(user.getPhone());
message.setReceiver(user.getName());
System.out.println("信息发送成功...收件人:"+message.getPhone()+" ||"+message.toString());
}
}
}
//抽象原型(抽象克隆方法)
interface MesClone extends Cloneable{
public MesClone clone();
}
//具体原型(短信类)
class Message implements MesClone{
private String receiver;//接收者
private String phone;//接收人电话号码
private String text;//发送信息内容
public Message(String text){
this.text=text;
}
public String getReceiver() {
return receiver;
}
public void setReceiver(String receiver) {
this.receiver = receiver;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
//实现克隆方法
public MesClone clone(){
try {
return (MesClone)super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}
//用户信息封装类
class User implements Cloneable{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
private String phone;
//克隆方法
public Object clone(){
try {
return (User)super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}
java中Object提供的clone()方法是“浅”克隆,即只复制关联对象的引用,而不复制关联对象的数据。如果需要“深”克隆,则需要在覆盖clone()方法时手动控制克隆的深度。
浅拷贝:创建一个新对象,然后将当前对象的非静态字段复制到该对象,如果字段类型是值类型(基本类型)的,那么对该字段进行复制;如果字段是引用类型的,则只复制该字段的引用而不复制引用指向的对象。此时新对象里面的引用类型字段相当于是原始对象里面引用类型字段的一个副本,原始对象与新对象里面的引用字段指向的是同一个对象。
深拷贝:即将引用类型的属性内容也拷贝一份新的。利用clone方式进行深拷贝就是将引用类型的类也实现Cloneable,然后对具体原型类的clone方法进行调整。