23种设计模式之原型模式

定义:用原型实例指定创建对象的种类,并通过拷贝这些原型创新的对象
类图:
这里写图片描述

  • Client:客户端用户
  • Prototype:抽象类或者接口,声明具备clone能力
  • ConcretePrototype:具体的原型类

使用场景:

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

实现方式:
原型模式主要用于对象的复制,它的核心是就是类图中的原型类Prototype。Prototype类需要具备以下两个条件:

  • 实现Cloneable接口。在java语言有一个Cloneable接口,它的作用只有一个,就是在运行时通知虚拟机可以安全地在实现了此接口的类上使用clone方法。在java虚拟机中,只有实现了这个接口的类才可以被拷贝,否则在运行时会抛出CloneNotSupportedException异常。
  • 重写Object类中的clone方法。Java中,所有类的父类都是Object类,Object类中有一个clone方法,作用是返回对象的一个拷贝,但是其作用域protected类型的,一般的类无法调用,因此,Prototype类需要将clone方法的作用域修改为public类型。
/**
 * Created by jmfstart on 2017/5/9.
 * 文档类型,扮演的是ConcretePrototype角色,而cloneable是代表prototype角色
 */
public class WordDocument implements Cloneable {
    //文本
    private String mText;
    //图片名列表
    private ArrayList<String> mImages = new ArrayList<>();

    public WordDocument(){
        System.out.println("------------WordDocument的构造函数");
    }

    @Override
    protected WordDocument clone(){
        try {
            WordDocument doc = (WordDocument) super.clone();
            doc.mText = this.mText;
            //对Images对象也调用clone()函数,进行深拷贝
            doc.mImages = (ArrayList<String>) this.mImages.clone();
            return doc;
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }

    public String getText() {
        return mText;
    }

    public void setText(String mText) {
        this.mText = mText;
    }

    public ArrayList<String> getImages() {
        return mImages;
    }

    public void addImages(String image) {
        mImages.add(image);
    }

    public void showDocument(){
        System.out.println("--------------Word Content Start--------------");
        System.out.println("Text:"+mText);
        System.out.println("Images List:");
        for (String imageName:mImages){
            System.out.println("image name :"+imageName);
        }
        System.out.println("--------------Word Content End--------------");
    }
}

public class Client {
    public static void main(String[] args){
        // 1 构建文档对象
        WordDocument originDoc = new WordDocument();
        // 2 编辑文档,添加图片等
        originDoc.setText("这是一篇文档");
        originDoc.addImages("图片一");
        originDoc.addImages("图片二");
        originDoc.addImages("图片三");
        originDoc.showDocument();

        // 以原始文档为原型,拷贝一份副本
        WordDocument doc2 = originDoc.clone();
        doc2.showDocument();
        // 修改文档副本,不会影响原始文档
        doc2.setText("这是修改过的Doc2文本");
        doc2.addImages("nihao.jpg");
        doc2.showDocument();

        originDoc.showDocument();
    }
}

使用时注意事项
原型模式是非常简单的一个模式,它的核心问题就是对原始对象进行拷贝,在这个模式的使用过程中需要注意的就是:深、浅拷贝的问题。为了减少错误,建议在使用该模式时尽量使用深拷贝,避免操作副本时影响原始对象的问题。
优点
原型模式是在内存中二进制流的拷贝,要比直接new一个对象性能好的多,特别是在一个循环体内产生大量的对象时,原型模式可以更好地体现其优点。
缺点
这既是它的优点也是缺点,直接在内存中拷贝,构造函数是不会执行的,在实际开发中应该注意这个潜在的问题,优点就是减少了约束,缺点也是减少了约束,需要大家在实际应用时考虑。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值