喵星之旅-沉睡的猫咪-原型模式
一、原型模式是什么?
用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。专业称呼为“CV大法”。
对于java中,复制对象的困难在我们很可能复制了当前对象,但是对象内的引用却只是拿来了,内部深层的对象没有重新创建,所以复制出的对象和原对象存在共用的部分,相互影响。也就是所谓的浅克隆和深克隆。本文只考虑深克隆。这种克隆的功能可以使单独的工具类,也可以是对象自身功能,这里只演示对象自身功能。
二、java代码实现原型模式
原型类(需要实现序列化接口)
package create.prototype; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.List; import com.alibaba.fastjson.JSON; /** * * @author bunny~~我是兔子我会喵,我叫喵星兔。 * 原型模式 */ public class MyPrototype implements Serializable { private static final long serialVersionUID = 1L; private String name; private int age; private List<String> title; /** * 通过序列化实现深度克隆 * @return */ public MyPrototype copyByIO() { try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(this); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); return (MyPrototype)ois.readObject(); }catch (Exception e){ e.printStackTrace(); return null; } } /** * 通过json实现深度克隆 * @return */ public MyPrototype copyByJson() { try { String jsonString = JSON.toJSONString(this); return (MyPrototype) JSON.parseObject(jsonString, this.getClass()); } catch (Exception e) { e.printStackTrace(); } return null; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public List<String> getTitle() { return title; } public void setTitle(List<String> title) { this.title = title; } @Override public String toString() { return "MyPrototype [name=" + name + ", age=" + age + ", title=" + title + "]"; } }
测试类
package create.prototype; import java.util.ArrayList; import java.util.List; public class Test { public static void main(String[] args) { MyPrototype p0 = new MyPrototype(); p0.setAge(11); p0.setName("kitty"); List<String> title = new ArrayList<>(); p0.setTitle(title ); System.out.println(p0); MyPrototype p1 = p0.copyByIO(); p1.getTitle().add("p1"); System.out.println(p0); System.out.println(p1); System.out.println(p0 == p1); System.out.println(p0.getTitle() == p1.getTitle()); MyPrototype p2 = p0.copyByJson(); p2.getTitle().add("p2"); System.out.println(p0); System.out.println(p2); System.out.println(p0 == p2); System.out.println(p0.getTitle() == p2.getTitle()); } }
三、总结
原型模式在编码过程中,绝对是所有设计模式出场频率最高的一种。正所谓“我们不是代码的生产者,我们只是代码的搬运工”。平时我们如果有一个需求,比如上传文件。这时我们不会找到相应的工具,然后去阅读操作手册(就是new对象的过程),而是找寻一个上传样例,用一种叫“CV”的技术实现在我们的代码中(原型模式),进而根据具体的环境进行调试,最终实现功能。
经典之中亦是不少原型的出现,比如“三人行必有我师”、“前事不忘后事之师”。但是是否选择原型还需进一步考虑。因为原型也不是万能的,原型的成功案例很多,但是失败的也是不少。如果各方面允许,其实不使用原型必然是安全的,当然可能不高效。当我们对对象目标了解程度足够高时,选择原型必然是事半功倍。任何的设计模式只要我们足够的掌控,都是我们手中的利器。在掌控不足的情况下也必然是手中的噩梦。
作者:喵星兔
出处:https://www.cnblogs.com/kittybunny/
喵星之旅:https://www.cnblogs.com/kittybunny/p/12148641.html
我的视频:https://space.bilibili.com/518581788
更多内容:不咬人的小兔子
本博客所有文章仅用于学习、研究和交流目的,欢迎非商业性质转载。
我是兔子,我会喵,我叫喵星兔~~