Java设计模式笔记之原型模式
来源:互联网 发布:暂七师军乐队 知乎 编辑:程序博客网 时间:2024/04/20 15:00
原型模式(Prototype),用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。(引用自——《大话设计模式》)
原型类:
public abstract class Prototype { private String id; public Prototype(String id) { this.id = id; } public String getId() { return id; } public abstract Prototype clone();}具体类:
public class ConcretePrototypeOne extends Prototype { public ConcretePrototypeOne(String id) { super(id); } @Override public Prototype clone() { //创建当前对象的浅表副本 return this.clone(); }}
客户端:
public class ResumeTestActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ConcretePrototypeOne p1 = new ConcretePrototypeOne("I"); ConcretePrototypeOne c1 = (ConcretePrototypeOne) p1.clone();//克隆对象 L.e("复制的:" + c1.getId()); }}
下面是一个具体的列子:
/** * Created by zsf * 原型模式 * WordDocument,文档类型,扮演的是ConcretePrototype角色,而cloneable是代表prototype角色 * 模拟了Word文档中的图片和文字元素, */public class WordDocument implements Cloneable{ //文本 private String mText; //图片名列表 private ArrayList<String> mImages = new ArrayList<>(); public WordDocument(){ L.e("--------------WordDocument构造函数"); } /** * 实现对象克隆,该方法不是Cloneable接口中的,而是Object中的方法。Cloneable也是一个标识接口,表明这个类的 * 对象是可以拷贝的。没有实现Cloneable接口却调用clone()方法会抛出异常 * @return * @throws CloneNotSupportedException */ @Override protected WordDocument clone() throws CloneNotSupportedException { WordDocument doc = (WordDocument) super.clone(); doc.mText = this.mText; doc.mImages = this.mImages; return doc; } public String getText(){ return mText; } public void setText(String mText){ this.mText = mText; } public List<String> getImages(){ return mImages; } public void addImage(String img){ this.mImages.add(img); } /** * 打印文档内容 */ public void showDoucment(){ L.e("----------word Content Start------"); L.e("Text:" + mText); L.e("Images List:"); for (String imgName : mImages){ L.e("image name :" + imgName); } L.e("------word Content End------"); }}客户端代码:
/** * Created by zsf * * 注意!!通过clone拷贝对象时,并不会执行构造函数 */public class WordDocumentTestActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //1.构建文档对象 WordDocument document = new WordDocument(); //2.编辑文档,添加图片等 document.setText("这是一篇文档"); document.addImage("图片1"); document.addImage("图片2"); document.addImage("图片3"); document.showDoucment(); try { //以原始文档为原型,拷贝一份副本 WordDocument copyDocument = document.clone(); copyDocument.showDoucment(); //修改文档副本,不会影响原始文档 copyDocument.setText("这是修改过的拷贝文档"); copyDocument.showDoucment(); document.showDoucment(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } }}我们发现上面的例子并没有Protototype抽象类,因为我们实现了Cloneable接口,并且重写了里面的clone()方法。
打印的Log
03-31 16:58:16.034 27552-27552/? E/zsf: --------------WordDocument构造函数03-31 16:58:16.034 27552-27552/? E/zsf: ----------word Content Start------03-31 16:58:16.035 27552-27552/? E/zsf: Text:这是一篇文档03-31 16:58:16.035 27552-27552/? E/zsf: Images List:03-31 16:58:16.035 27552-27552/? E/zsf: image name :图片103-31 16:58:16.035 27552-27552/? E/zsf: image name :图片203-31 16:58:16.035 27552-27552/? E/zsf: image name :图片303-31 16:58:16.035 27552-27552/? E/zsf: ------word Content End------03-31 16:58:16.035 27552-27552/? E/zsf: ----------word Content Start------03-31 16:58:16.035 27552-27552/? E/zsf: Text:这是一篇文档03-31 16:58:16.035 27552-27552/? E/zsf: Images List:03-31 16:58:16.035 27552-27552/? E/zsf: image name :图片103-31 16:58:16.035 27552-27552/? E/zsf: image name :图片203-31 16:58:16.035 27552-27552/? E/zsf: image name :图片303-31 16:58:16.035 27552-27552/? E/zsf: ------word Content End------03-31 16:58:16.035 27552-27552/? E/zsf: ----------word Content Start------03-31 16:58:16.035 27552-27552/? E/zsf: Text:这是修改过的拷贝文档03-31 16:58:16.035 27552-27552/? E/zsf: Images List:03-31 16:58:16.035 27552-27552/? E/zsf: image name :图片103-31 16:58:16.035 27552-27552/? E/zsf: image name :图片203-31 16:58:16.035 27552-27552/? E/zsf: image name :图片303-31 16:58:16.035 27552-27552/? E/zsf: ------word Content End------03-31 16:58:16.036 27552-27552/? E/zsf: ----------word Content Start------03-31 16:58:16.036 27552-27552/? E/zsf: Text:这是一篇文档03-31 16:58:16.036 27552-27552/? E/zsf: Images List:03-31 16:58:16.036 27552-27552/? E/zsf: image name :图片103-31 16:58:16.036 27552-27552/? E/zsf: image name :图片203-31 16:58:16.036 27552-27552/? E/zsf: image name :图片303-31 16:58:16.036 27552-27552/? E/zsf: ------word Content End------
谈及原型模式,不得不说的一个知识点就是浅拷贝和深拷贝
上面原型模式的实现只是一个浅拷贝,又称影子拷贝。原理就是副本文档的字段引用原始文档的字段。
我们知道A引用B就是两个对象指向同一个地址,当修改A时B也会改变,B修改时A同样会改变。
如何解决上面的问题就是要使用深拷贝。
深拷贝,即在拷贝对象的同时,对于引用型的字段也要采用拷贝的形式,而不是单纯引用形式。clone方法修改如下:
/*** 克隆对象*/@Overrideprotected WordDocument clone(){try{WordDocument doc = (WordDocument)super.clone();doc.mText = this.mText;//对mImages对象也调用clone()函数,进行深拷贝doc.mImages = (ArrayList<String>)this.mImages.clone();return doc;}catch(Exception e){}return null;}
上面中doc.mImages指向了this.mImages的一份拷贝,而不是this.mImages本身,这样在copyDocument中添加图片不会影响原Document。
原型模式是简单的一个模式,核心问题就是对原始对象进行拷贝,在使用该模式时需要注意的就是深浅拷贝的问题,建议直接使用深拷贝。
0 0
- java设计模式笔记之原型模式
- Java设计模式笔记之原型模式
- java设计模式之原型设计模式
- 设计模式学习笔记之原型模式
- 设计模式学习笔记之原型模式
- 设计模式之禅笔记-原型模式
- java设计模式学习笔记-原型模式
- java 设计模式之原型模式Prototype
- Java:设计模式之原型模式(Prototype)
- java设计模式之原型模式
- java设计模式之原型模式
- java设计模式之原型模式
- 【Java设计模式】之原型模式
- Java设计模式之原型模式(7)
- Java--设计模式之原型模式
- JAVA设计模式之原型模式
- Java设计模式之原型模式
- JAVA设计模式之原型模式
- java.lang.ClassCastException: hibernatehand.entity.Grade_$$_javassist_1 cannot be cast to javassist.
- 解决在JDK8中org.aspectj.apache.bcel.classfile.ClassFormatException Invalid byte tag in constant pool: 18
- 从尾到头打印单链表
- IntelliJ IDEA 同一窗口查看多个项目(模块),就像eclipse一样
- android解决app开启瞬间白屏的问题
- Java设计模式笔记之原型模式
- HDU4027线段树
- hdu 1085
- Android 开发,关于依赖库的制作,打包aar,及使用过程
- ZigBee_2530初学笔记
- pyspark + mongodb
- 学习运维——虚拟机管理
- 自动配置ssh公私钥
- RecyclerView加载不同类型的布局