美文网首页
原型模式

原型模式

作者: milovetingting | 来源:发表于2020-01-15 01:16 被阅读0次

    个人博客

    http://www.milovetingting.cn

    原型模式

    模式介绍

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

    模式定义

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

    使用场景

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

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

    3. 一个对象需要提供给其它对象访问,而且各个调用者可能都需要修改值

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

    简单实现

    以简单的文档拷贝为例演示简单的原型模式。

    先来演示浅拷贝

    文档定义

    public class Document implements Cloneable {
    
        private String mText;
        private ArrayList<String> mImages = new ArrayList<>();
    
        public String getmText() {
            return mText;
        }
    
        public void setmText(String mText) {
            this.mText = mText;
        }
    
        public List<String> getmImages() {
            return mImages;
        }
    
        public void addImage(String image) {
            mImages.add(image);
        }
    
        public void showDocument() {
            System.out.println(this);
        }
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            Document doc = (Document) super.clone();
            doc.mText = this.mText;
            doc.mImages = this.mImages;
            return doc;
        }
    
        @Override
        public String toString() {
            return "Document [mText=" + mText + ", mImages=" + mImages + "]";
        }
    
    }
    

    调用

    public static void main(String[] args) {
            Document doc1 = new Document();
            doc1.setmText("文档1");
            doc1.addImage("图片1");
            doc1.showDocument();
            Document doc2;
            try {
                doc2 = (Document) doc1.clone();
                doc2.setmText("文档2");
                doc2.addImage("图片2");
                doc2.showDocument();
                doc.showDocument();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
    
        }
    

    创建文档1,然后显示文档1的内容。然后拷贝了文档1,修改了文档1的内容,然后依次显示文档2,文档1

    输出结果

    Document [mText=文档1, mImages=[图片1]]
    Document [mText=文档2, mImages=[图片1, 图片2]]
    Document [mText=文档1, mImages=[图片1, 图片2]]
    

    可以看到,修改拷贝后的文档2的Text,文档1没有受影响,但是修改文档2的Images,文档1也被修改了。

    下面演示深拷贝

    只需要修改clone方法

    @SuppressWarnings("unchecked")
        @Override
        protected Object clone() throws CloneNotSupportedException {
            Document doc = (Document) super.clone();
            doc.mText = this.mText;
            //doc.mImages = this.mImages;
            doc.mImages = (ArrayList<String>) this.mImages.clone();
            return doc;
        }
    

    再次运行后的输出结果:

    Document [mText=文档1, mImages=[图片1]]
    Document [mText=文档2, mImages=[图片1, 图片2]]
    Document [mText=文档1, mImages=[图片1]]
    

    修改文档2的Images并没有影响到文档1。

    小结

    原型模式本质上就是对象拷贝,容易出现的问题是深拷贝、浅拷贝。使用原型模式可以解决构建复杂对象的资源消耗问题,能够在某些场景下提升创建对象的效率。还有一个重要用途是保护性拷贝,也就是某个对象对外可能是只读的,为了防止外部对这个只读对象修改,可以通过返回一个对象拷贝的形式来实现只读的限制。

    相关文章

      网友评论

          本文标题:原型模式

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