Android设计模式--原型模式

心平能愈三千疾,心静可通万事理

一,定义

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

也就是说用户从一个实例中复制出一个内部属性一致的对象,这个被复制的对象就是原型。

原型模式多用于创建复杂的或者构造耗时的实例,因为这种情况下复制一个已经存在的实例可使程序运行更高效。

二,使用场景

1,类初始化需要消耗非常多的资源

2,通过new产生一个对象需要非常繁琐的数据准备或访问权限

3,一个对象需要提供给其他对象访问,而且各个调用者都可能会修改其值时,可以使用原型模式拷贝多个对象供调用者使用,即保护性拷贝

注意:通过实现Cloneable接口的原型模式在调用clone函数构造实例时并不一定比通过new操作速度快,只有当通过new构造对象较为耗时时,通过clone方法才能获得效率上的提高。

三,通过Cloneable实现原型模式

假设有这样一个需求,用户通过网络请求获取到服务器上的用户信息,其他模块可以拿到用户信息,本地修改用户信息以供展示用,但是各个模块拿到的用户信息必须得是服务器上请求的原始的用户信息。

这种情况下我们就可以使用原型模式来实现。

首先新建我们的user类:实现clone方法,拷贝对象

/**
 * 用户信息 实现cloneable接口
 * */
public class User implements Cloneable {

    private String userName;

    private int age;

    private String address;

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getUserName() {
        return userName;
    }

    public int getAge() {
        return age;
    }

    public String getAddress() {
        return address;
    }

    @NonNull
    @Override
    protected User clone() throws CloneNotSupportedException {
        User user = (User) super.clone();
        user.userName =this.userName;
        user.address =this.address;
        user.age =this.age;
        return user;
    }
}

然后创建缓存数据类,注意,返回的是User的clone对象:

public class UserDao {

    private User user;

    private UserDao(){

    }

    public static UserDao getInstance(){
        return UserDao.SingletonHolder.userDao;
    }

    private static class SingletonHolder{
        private static final UserDao userDao =new UserDao();
    }

    public void setUser(User user) {
        this.user = user;
    }

    public User getUser() {
        try {
            return user.clone();
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
    }
}

然后模拟服务器获取数据和不同模块间设置用户信息的操作:

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getUserFromNet();
        setUserAgeM1();
        setUserAgeM2();

    }

    /**
     * 模拟从服务器获取user数据存到本地
     * */
    public void getUserFromNet(){
        User user =new User();
        user.setUserName("袁震");
        user.setAge(20);
        user.setAddress("淄博");
        UserDao.getInstance().setUser(user);
    }
    /**
     * 模拟M1模块设置年龄
     * */
    public void setUserAgeM1(){
        User user =UserDao.getInstance().getUser();
        Log.d(TAG,"yz-----M1模块获得年龄:"+user.getAge());
        user.setAge(28);
        Log.d(TAG,"yz-----M1模块设置年龄:"+user.getAge());
    }
    /**
     * 模拟M2模块获得年龄
     * */
    public void setUserAgeM2(){
        User user =UserDao.getInstance().getUser();
        Log.d(TAG,"yz-----M2模块获得年龄:"+user.getAge());
        user.setAge(30);
        Log.d(TAG,"yz-----M2模块设置年龄:"+user.getAge());
    }


}

最后输出结果:

四,通过其他方式实现原型模式

原型模式不一定必须通过实现cloneable接口来实现,因为有时候拷贝的效率并不一定比new的效率高。

在上述案例中,User类也可以这样实现:

/**
 * 用户信息 实现cloneable接口
 * */
public class User {

    private String userName;

    private int age;

    private String address;

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getUserName() {
        return userName;
    }

    public int getAge() {
        return age;
    }

    public String getAddress() {
        return address;
    }

   
    protected User clone(){
        User user = new User();
        user.userName =this.userName;
        user.address =this.address;
        user.age =this.age;
        return user;
    }
}

五,总结

原型模式本质上就是对象拷贝,与C++中的深拷贝,浅拷贝类似,不了解的可以查看文章Android JNI2--C++基础-CSDN博客

优点:原型模式是在内存中二进制流的拷贝,要比直接new一个对象性能好很多,特别是要在一个循环体内产生大量的对象时,原型模式可以更好的体现其优点

缺点:直接在内存中拷贝,构造函数是不会执行的,实际开发时需要注意

参考文献:Android源码设计模式解析与实战第二版

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

袁震

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值