java 原型模式作用_Java设计模式,原型模式

一、原型模式

原型模式与构造器模式、单例模式、工厂方法模式、抽象工厂模式一样,都属于创建型模式。原型模式理解起来,相对简单,来看下其定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

原型模式的实例的拷贝包括浅复制和深复制:浅复制:将一个对象复制后,其基本数据类型的变量都会重新创建,而引用类型的变量指向的还是原对象所指向的,也就是指向的内存堆地址没变。

深复制:将一个对象复制后,不论是基本数据类型还是引用类型,都是重新创建的。

从以上可以看出,浅复制中的引用类型只是复制了变量的值,其地址仍然没变;而深复制完全复制了变量,复制后变量地址会有所变化。

有一个消息类,其属性及方法声明如下:

public class Message implements Cloneable, Serializable {

private String name; //消息名称

private String size; //消息大小

private int type; //消息类型

private Date date; //创建日期

public static final int TEXT = 0x01;

public static final int PIC = 0x02;

public static final int VIDEO = 0x03;

public static final int MIX = 0x04;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getSize() {

return size;

}

public void setSize(String size) {

this.size = size;

}

public int getType() {

return type;

}

public void setType(int type) {

this.type = type;

}

public Date getDate() {

return date;

}

public void setDate(Date date) {

this.date = date;

}

public Message clone() throws CloneNotSupportedException {

return (Message) super.clone();

}

public Message deepClone() throws CloneNotSupportedException,

IOException, ClassNotFoundException {

//把对象写入到字节流中

ByteArrayOutputStream baos =new ByteArrayOutputStream();

ObjectOutputStream oos = new ObjectOutputStream(baos);

oos.writeObject(this);

//把字节流转化为对象

ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());

ObjectInputStream ois = new ObjectInputStream(bais);

return (Message) ois.readObject();

}

@Override

public String toString() {

String tos = "name[" + name + "],size[" + size +

"],type[" + type + "],date[" + date + "]";

return tos;

}

public static void main(String[] a) {

Message msg = new Message();

msg.setName("好友消息");

msg.setSize("123KB");

msg.setType(Message.TEXT);

msg.setDate(new Date());

System.out.println("msg:" + msg.toString());

try {

Message cloneMsg = msg.clone();

System.out.println("msg:" + msg.toString());

System.out.println("cloneMsg:" + cloneMsg.toString());

System.out.println(cloneMsg.getDate() == msg.getDate());

System.out.println(cloneMsg.getName() == msg.getName());

System.out.println(cloneMsg.getType() == msg.getType());

} catch (Exception e) {

e.printStackTrace();

}

}

}

通过实现Cloneable接口,java默认的实现方式是浅复制,而非深复制。由于Object并没有实现Cloneable接口,所以子类必须实现Cloneable,并调用基类的clone方法才能实现浅复制。

要实现深复制,Message类需要实现序列化,通过对象流与字节流之间的转化,达到深复制的目的。

Message类中的deepClone方法就是深复制的实现。

以上main方法的执行结果如下:

msg:name[好友消息],size[123KB],type[1],date[Tue Apr 05 17:47:56 CST 2016]

msg:name[好友消息],size[123KB],type[1],date[Tue Apr 05 17:47:56 CST 2016]

cloneMsg:name[好友消息],size[123KB],type[1],date[Tue Apr 05 17:47:56 CST 2016]

true

true

true

说明,浅复制只是复制了引用类型的值,并没有改变其地址,指向的仍然是原对象的变量地址。

在main方法中调用deepClone方法:

public static void main(String[] a) {

......

Message cloneMsg = msg.deepClone();

......

}

最后的输出结果如下:

msg:name[好友消息],size[123KB],type[1],date[Tue Apr 05 17:54:39 CST 2016]

msg:name[好友消息],size[123KB],type[1],date[Tue Apr 05 17:54:39 CST 2016]

cloneMsg:name[好友消息],size[123KB],type[1],date[Tue Apr 05 17:54:39 CST 2016]

false

false

true

可以看出,深复制下,引用类型变成了完全的复制,所有的引用类型地址都变化了。

二、jdk中的原型模式

jdk中大部分类都提供了克隆的方法,比如Date类:

public class Date

implements java.io.Serializable, Cloneable, Comparable

{

public Object clone() {

Date d = null;

try {

d = (Date)super.clone();

if (cdate != null) {

d.cdate = (BaseCalendar.Date) cdate.clone();

}

} catch (CloneNotSupportedException e) {} // Won't happen

return d;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值