美文网首页
设计模式之原型模式

设计模式之原型模式

作者: Kevin_小飞象 | 来源:发表于2019-04-03 13:36 被阅读0次

    定义

    用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。被复制的实例就是“原型”,这个原型是可定制的。

    Android 源码中的原型模式

    1. Intent

    特点

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

      (2)还有一个重要的用途就是保护性拷贝,也就是对某个对象对外可能是只读的,为了防止外部对这个只读对象的修改,通常可以通过返回一个对象拷贝的形式实现只读的限制。

    • 缺点:
      (1)这既是它的优点也是缺点,直接在内存中拷贝,构造函数是不会执行的,在实际开发中应该注意这个潜在问题。优点是减少了约束,缺点也是减少了约束,需要大家在实际应用时考虑。

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

    使用场景

    (1)类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等,通过原型拷贝避免这些消耗。
    (2)通过new产生的一个对象需要非常繁琐的数据准备或者权限,这时可以使用原型模式。
    (3)一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用,即保护性拷贝。

    简单实现

    /**
     * Created on 2019/4/3 11:41
     *
     * @author 小飞象
     */
    public class Book implements Cloneable {
        private int price;
        private String title;
        private String content;
        private ArrayList<String> images = new ArrayList<>();
    
        public Book() {
            super();
        }
    
        public Book(int price, String title, String content) {
            this.price = price;
            this.title = title;
            this.content = content;
        }
    
        public int getPrice() {
            return price;
        }
    
        public void setPrice(int price) {
            this.price = price;
        }
    
        public String getTitle() {
            return title;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        public String getContent() {
            return content;
        }
    
        public void setContent(String content) {
            this.content = content;
        }
    
        public ArrayList<String> getImage() {
            return images;
        }
    
        public void addImage(String image) {
            this.images.add(image);
        }
    
        @Override
        public Object clone() throws CloneNotSupportedException {
            Book book = (Book) super.clone();
            return book;
        }
    
        public void showBook() {
            Log.d("book", "=====start=====");
    
            Log.d("book", "title:"+title);
            for(String img : images){
                Log.d("book", "image name:"+img);
            }
    
            Log.d("book", "======End======");
    
        }
    }
    

    使用:

    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            initData();
        }
    
        private void initData() {
            try {
                Book book1 = new Book(50,"书1","内容");
                book1.addImage("图1");
                book1.showBook();
    
                Book book2 = (Book) book1.clone();
                book2.showBook();
    
                book2.setTitle("书2");
                book2.addImage("图2");
                book2.showBook();
    
                book1.showBook();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
        }
    }
    

    结果:


    book1.jpg

    这里我们发现通过修改book2后,只是影响了book1的image,而没有改变title。这是为什么呢?这个我们暂时放下,先看看变化的image,很明显book1与book2是引用了同一地址,所以一方修改两边都改变。那么怎么解决?覆盖Object中的clone方法,实现深拷贝。同时我们称上面的原型模式为浅拷贝。

    相关文章

      网友评论

          本文标题:设计模式之原型模式

          本文链接:https://www.haomeiwen.com/subject/kapabqtx.html