股票场内基金交易,没时间盯盘?
简介
本书第四章介绍了原型模式。
原型模式介绍
用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。被复制的实例就是“原型”,这个原型是可定制的。
使用场景
1.类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等,通过原型拷贝避免这些消耗。
2.通过 new 产生的一个对象需要非常繁琐的数据准备或者权限,这时可以使用原型模式。
3.一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用,即保护性拷贝。
简单实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
public class WordDocument implements Cloneable { // 文本 private String mText; // 图片名列表 private ArrayList<String> mImages = new ArrayList<String>(); public WordDocument() { System.out .println("-----------------WordDocument构造函数------------------"); } public String getmText() { return mText; } public void setmText(String mText) { this.mText = mText; } public ArrayList<String> getmImages() { return mImages; } public void addImage(String img) { this.mImages.add(img); } /** * 打印文档内容 */ public void showDocument() { System.out.println("------------word Content Start--------------"); System.out.println("Text:" + mText); System.out.println("Images List:"); for (String imgName : mImages) { System.out.println("image name:" + imgName); } System.out.println("------------word Content End--------------"); } } public class Client { public static void main(String[] args) { //1.构建文档对象 WordDocument originDoc=new WordDocument(); //2.编辑文档,添加图片内容 originDoc.setmText("这是一篇文档"); originDoc.addImage("图片 1"); originDoc.addImage("图片 2"); originDoc.addImage("图片 3"); originDoc.showDocument(); //以原始文档为原型,拷贝一份副本 WordDocument doc2=originDoc.clone(); doc2.showDocument(); //修改文档副本 doc2.setmText("修改"); doc2.addImage("哈哈.jpg"); doc2.showDocument(); originDoc.showDocument(); } } |
运行结果如下:
可以看到,originDoc 和 doc2 在 Text 修改之后输出是不一样的,但是在 doc2 中 doc2.addImage(“哈哈.jpg”) 之后,originDoc 也输出了 哈哈.jpg,说明这只是简单的浅拷贝,引用类型的的新对象 doc2 的 mImages 只是单纯地指向了 this.mImages 引用,并没有重新构造一个 mImages 对象。所以在原型模式里最需要注意的就是深拷贝和浅拷贝,使用深拷贝可以避免操作副本时影响原始对象的问题。我们在这里可以这么做:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
@Override protected WordDocument clone() { try { WordDocument doc = (WordDocument) super.clone(); doc.mText = this.mText; ; doc.mImages = (ArrayList<String>) this.mImages.clone(); return doc; } catch (Exception e) { e.printStackTrace(); } return null; } |
我们将 doc.mImages 指向 this.mImages 的一份拷贝,而不是 this.mImages 本身,所以在 doc2 添加图片不会影响 originDoc。结果如下:
Android源码中的原型模式
1 2 3 4 5 6 7 |
Uri uri = Uri.parse("smsto:110"); Intent intent = new Intent(Intent.ACTION_SEND,uri); intent.putExtra("sms_body", "The SMS text"); //克隆 Intent intent2 = (Intent)intent.clone(); startActivity(intent2); |
总结
优点
1.原型模式是在内存中二进制流的拷贝,要比直接new一个对象性能好很多,特别是要在一个循环体内产生大量对象时,原型模式可能更好的体现其优点。
2.还有一个重要的用途就是保护性拷贝,也就是对某个对象对外可能是只读的,为了防止外部对这个只读对象的修改,通常可以通过返回一个对象拷贝的形式实现只读的限制。
缺点:
1.这既是它的优点也是缺点,直接在内存中拷贝,构造函数是不会执行的,在实际开发中应该注意这个潜在问题。优点是减少了约束,缺点也是减少了约束,需要大家在实际应用时考虑。
2.通过实现Cloneable接口的原型模式在调用clone函数构造实例时并不一定比通过new操作速度快,只有当通过new构造对象较为耗时或者说成本较高时,通过clone方法才能够获得效率上的提升。
参考资料
《Android 源码设计模式解析与实战 》
想获得去掉 5 元限制的证券账户吗?

如果您想去掉最低交易佣金 5 元限制,使用微信扫描左边小程序二维码,访问微信小程序「优财助手」,点击底部菜单「福利」,阅读文章「通过优财开证券账户无最低交易佣金 5 元限制」,按照文章步骤操作即可获得免 5 元证券账户,股票基金交易手续费率万 2.5。
请注意,一定要按照文章描述严格操作,如错误开户是无法获得免 5 元证券账户的。