原型模式(prototype)
通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。
就是java的克隆技术,以某个对象为原型,复制出新的对象。显然新的对象具备原型对象的特点。
优势:效率高(直接克隆,避免了重新执行构造过程步聚)。
克隆类似于new,但是不同于new。New创建新的对象属性采用的默认值。克隆出的对象属性值的原型对象相同。并且克隆出的新对象改变不会影响原型对象。然后在修改克隆对象的值。
原型模式的实现:
Cloneable接口和Clone方法。
Prototype模式中实现起来最困难的地方就是内存复制操作,所幸java中提供了clone()方法替我们做了绝大部他事情。
注意用词:克隆和拷贝是一回事。
浅克隆
publicclass User implements Cloneable { private String name; private Date birthday;
public String getName() { returnname; }
publicvoid setName(String name) { this.name = name; }
public Date getBirthday() { returnbirthday; }
publicvoid setBirthday(Date birthday) { this.birthday = birthday; }
public User() { }
@Override protected Object clone() { Object obj; try { obj = super.clone(); return obj; } catch (CloneNotSupportedException e) { e.printStackTrace(); } returnnull; } } | publicclass Main { publicstaticvoid main(String[] args) { Date date = new Date(1234L); User user1 = new User(); user1.setName("Lucy"); user1.setBirthday(date); System.out.println(user1.getName()); System.out.println(user1.getBirthday());
//修改时间。 date.setTime(13145656789L); user1.setBirthday(date); System.out.println(user1.getBirthday());
//调用克隆方法复制类 User user2 = (User) user1.clone(); System.out.println(user2.getName()); System.out.println(user2.getBirthday()); } }
输出结果: Lucy Thu Jan 01 08:00:01 CST 1970 Tue Jun 02 11:34:16 CST 1970 Lucy Tue Jun 02 11:34:16 CST 1970
|
深克隆
publicclass User implements Cloneable { private String name; private Date birthday; public String getName() { returnname; } publicvoid setName(String name) { this.name = name; } public Date getBirthday() { returnbirthday; } publicvoid setBirthday(Date birthday) { this.birthday = birthday; } public User() { } @Override public Object clone() { Object obj; try { obj = super.clone(); //添加如下代码,进行深克隆。 User user2 = (User) obj; //克隆一个类的属性。 user2.birthday = (Date) this.birthday.clone(); return obj; } catch (CloneNotSupportedException e) { e.printStackTrace(); } returnnull; } } | publicclass Main { publicstaticvoid main(String[] args) { Date date = new Date(1234L); User user1 = new User(); //调用克隆方法复制类 user1.setName("Lucy"); user1.setBirthday(date); User user2 = (User) user1.clone(); System.out.println(user1.getName()); System.out.println(user1.getBirthday());
//修改时间。 date.setTime(13145656789L); user1.setBirthday(date); System.out.println("user1的生日:"+user1.getBirthday()); user2.setName("Rows"); System.out.println(user2.getName()); System.out.println("user2的生日:"+user2.getBirthday()); } } 输出结果: Lucy Thu Jan 01 08:00:01 CST 1970 user1的生日:Tue Jun 02 11:34:16 CST 1970 Rows user2的生日:Thu Jan 01 08:00:01 CST 1970 开发中的应用场景: 原型模式很少出现,一般是和工厂方法一起出现,通过clone的方法创建一个对象,然后由工厂方法提供给调用者。 Spring中的bean的创建实际上就是两种:单例模式和原型模式。(当然,原型模式需要和工厂模式搭配起来)。 |
利用序列化和反序列化技术实现深克隆
publicstaticvoid main(String[] args) throws Exception { Date date = new Date(1234L); User user1 = new User(); // 调用克隆方法复制类 user1.setName("Lucy"); user1.setBirthday(date); User user2 = (User) user1.clone();
// 通过序列化和反序列化深复制对象 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(user1); byte[] by = bos.toByteArray(); //反序列化 ByteArrayInputStream bin = new ByteArrayInputStream(by); ObjectInputStream ois = new ObjectInputStream(bin); User user3 = (User) ois.readObject();
System.out.println(user1.getName()); System.out.println(user1.getBirthday());
// 修改时间。 date.setTime(13145656789L); user1.setBirthday(date); System.out.println("user1的生日:" + user1.getBirthday()); user2.setName("Rows"); System.out.println(user2.getName()); System.out.println("user2的生日:" + user2.getBirthday());
System.out.println(user3.getName()); System.out.println("user3的生日:" + user3.getBirthday()); } 输出内容: Lucy Thu Jan 01 08:00:01 CST 1970 user1的生日:Tue Jun 02 11:34:16 CST 1970 Rows user2的生日:Thu Jan 01 08:00:01 CST 1970 Lucy user3的生日:Thu Jan 01 08:00:01 CST 1970
|