Android设计模式-原型模式

来源:互联网 发布:mac蓝牙发送文件 编辑:程序博客网 时间:2024/05/21 10:45

好久没有写新的文章了,趁这国庆没什么事,来理一理Android的设计模式。
感觉设计模式很多都应用于Android的源码当中,而且很大一部分都是使用Java的面向接口编程思想。学习Android的设计模式,对于面向接口的编程思想很有帮助,可以帮助理解Android的源码,还是很有用的。那我们就从Android的编程模式的创建模型来学习。

原型模式挺简单的,实用性也比较高,我们先看下他的定义:

用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。

啊,好吧。其实这个模式主要就是拷贝对象,重写一个clone();方法。这个模式:主要作用就是提高对象创建的效率。分为:浅拷贝和深度拷贝

浅拷贝:在pojo中实现cloneable接口,然后覆写clone();方法。在代码中调用clone();方法就可以了。

public class CloneBean implements Cloneable{    private String str;    private TestBean testBean;    public String getStr() {        return str;    }    public void setStr(String str) {        this.str = str;    }    public TestBean getTestBean() {        return testBean;    }    public void setTestBean(TestBean testBean) {        this.testBean = testBean;    }    @Override    protected Object clone() throws CloneNotSupportedException {        return super.clone();    }}

然后在代码中调用clone();方法
那我们来看下浅拷贝的实现状况:

public class ExampleUnitTest {    @Test    public void addition_isCorrect() throws Exception {        CloneBean cloneBean = new CloneBean();        cloneBean.setStr("aaa");        cloneBean.setTestBean(new TestBean("bbb"));        try {            CloneBean cloneBean2 = (CloneBean) cloneBean.clone();            System.out.println(cloneBean2.getStr()+"---"+cloneBean2.getTestBean().getA());            System.out.println(cloneBean2.toString()+"---"+cloneBean.toString());            System.out.println(cloneBean2.getTestBean().toString()+"---"+cloneBean.getTestBean().toString());            cloneBean.setStr("ccc");            cloneBean.getTestBean().setA("ddd");            System.out.println(cloneBean2.getStr()+"---"+cloneBean.getStr());            System.out.println(cloneBean2.getTestBean().getA()+"---"+cloneBean.getTestBean().getA());            System.out.println("==========================================================");            CloneBean cloneBean3 = cloneBean;            System.out.println(cloneBean3.getStr()+"---"+cloneBean2.getTestBean().getA());            System.out.println(cloneBean3.toString()+"---"+cloneBean.toString());            System.out.println(cloneBean3.getTestBean().toString()+"---"+cloneBean.getTestBean().toString());            cloneBean.setStr("eee");            cloneBean.getTestBean().setA("fff");            System.out.println(cloneBean3.getStr()+"---"+cloneBean.getStr());            System.out.println(cloneBean3.getTestBean().getA()+"---"+cloneBean.getTestBean().getA());        } catch (CloneNotSupportedException e) {            e.printStackTrace();        }    }}

这个是原型模式的测试代码

aaa---bbbcom.example.mytouchapp.CloneBean@1376c05c---com.example.mytouchapp.CloneBean@51521cc1com.example.mytouchapp.TestBean@1b4fb997---com.example.mytouchapp.TestBean@1b4fb997aaa---cccddd---ddd==========================================================ccc---dddcom.example.mytouchapp.CloneBean@51521cc1---com.example.mytouchapp.CloneBean@51521cc1com.example.mytouchapp.TestBean@1b4fb997---com.example.mytouchapp.TestBean@1b4fb997eee---eee

可以看到被复制的对象cloneBean2的变量的值跟cloneBean的是是一模一样的。而且cloneBean内的对象TestBean和cloneBean2的居然连内存地址都一模一样。这就意味着:浅拷贝的时候,被拷贝对象内里面如果有也有对象存在,那么这个对象并不在拷贝范围内,这个内部的对象只要改变,cloneBean和cloneBean2的TestBean都会发生改变。这个时候,就需要用深度拷贝了,将对象内部的变量全部都拷贝一遍。“

在原来cloneBean的基础上,重写clone方法:
i

  @Override    protected Object clone() throws CloneNotSupportedException {        CloneBean doc = (CloneBean) super.clone();        //如果要深度拷贝        doc.str = this.str;        doc.testBean = (TestBean) this.testBean.clone();        return doc;    }

实际上就相当于是把整个对象迭代一遍,将所有对象的变量重新拷贝一遍。看看打印输出:

aaa---bbbcom.example.mytouchapp.CloneBean@1376c05c---com.example.mytouchapp.CloneBean@51521cc1com.example.mytouchapp.TestBean@1b4fb997---com.example.mytouchapp.TestBean@deb6432aaa---cccbbb---ddd==========================================================ccc---bbbcom.example.mytouchapp.CloneBean@51521cc1---com.example.mytouchapp.CloneBean@51521cc1com.example.mytouchapp.TestBean@deb6432---com.example.mytouchapp.TestBean@deb6432eee---eeefff---fff

这个时候两个testBean的内存地址都不一样,说明拷贝成功了。

原型模式测试代码github: https://github.com/zhoukeda/PrototypeDemo