美文网首页
原型模式详解

原型模式详解

作者: 奋斗的韭菜汪 | 来源:发表于2020-06-16 20:29 被阅读0次

不通过new(构造方法)创建对象,通过clone,或者copy的操作创建对象
使用场景:
1、类初始化消耗资源较多
2、new产生的一个对象需要非常繁琐的过程(数据准备、访问权限等)
3、构造函数比较复杂
4、循环体中产生大量的对象时(比较常见)

浅克隆
jdk 的Cloneable是一个浅克隆
修改克隆对象后,原型对象也会发生变化(对于string这种应用类型clone只是copy了指针,并没有copy具体的值,修改是修改具体的值,所有原对象也会发生改变)

深克隆
1、序列化和反序列化
2、对象转json字符串,json字符串再转对象
深克隆的问题:性能不好,占用io
可以破坏单例(解决办法:不实现Cloneable接口,或者实现Cloneable接口重写clone方法,返回单例模式对外提供的唯一一个实例)
原型模式和单例模式是冲突的,不能同时存在一个对象中
1、简单实现:


public class BeanUtils {

    public static Object copy(Object prototype){
        Class clazz = prototype.getClass();
        Object instance = null;
        try {
            instance = clazz.newInstance();
            for(Field field : clazz.getDeclaredFields()){
                field.setAccessible(true);
                field.set(instance, field.get(prototype));
            }
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return instance;
    }
}
public class ExamPaper {
    private String attribute1;
    private String attribute2;
    private String attribute3;
    private String attribute4;
    private String attribute5;
    private String attribute6;
    private String attribute11;
    private String attribute7;
    private String attribute8;
    private String attribute9;
    private String attribute10;

    public ExamPaper copy(){
        ExamPaper examPaper = new ExamPaper();
        examPaper.setAttribute1(this.attribute1);
        examPaper.setAttribute2(this.attribute2);
        examPaper.setAttribute3(this.attribute3);
        examPaper.setAttribute4(this.attribute4);
        examPaper.setAttribute5(this.attribute5);
        examPaper.setAttribute6(this.attribute6);
        examPaper.setAttribute7(this.attribute7);
        examPaper.setAttribute8(this.attribute8);
        examPaper.setAttribute9(this.attribute9);
        examPaper.setAttribute10(this.attribute10);
        examPaper.setAttribute11(this.attribute11);
        return examPaper;

    }
    public String getAttribute1() {
        return attribute1;
    }
    public void setAttribute1(String attribute1) {
        this.attribute1 = attribute1;
    }
    public String getAttribute2() {
        return attribute2;
    }
    public void setAttribute2(String attribute2) {
        this.attribute2 = attribute2;
    }
    public String getAttribute3() {
        return attribute3;
    }
    public void setAttribute3(String attribute3) {
        this.attribute3 = attribute3;
    }
    public String getAttribute4() {
        return attribute4;
    }
    public void setAttribute4(String attribute4) {
        this.attribute4 = attribute4;
    }
    public String getAttribute5() {
        return attribute5;
    }
    public void setAttribute5(String attribute5) {
        this.attribute5 = attribute5;
    }
    public String getAttribute6() {
        return attribute6;
    }
    public void setAttribute6(String attribute6) {
        this.attribute6 = attribute6;
    }
    public String getAttribute11() {
        return attribute11;
    }
    public void setAttribute11(String attribute11) {
        this.attribute11 = attribute11;
    }
    public String getAttribute7() {
        return attribute7;
    }
    public void setAttribute7(String attribute7) {
        this.attribute7 = attribute7;
    }
    public String getAttribute8() {
        return attribute8;
    }
    public void setAttribute8(String attribute8) {
        this.attribute8 = attribute8;
    }
    public String getAttribute9() {
        return attribute9;
    }
    public void setAttribute9(String attribute9) {
        this.attribute9 = attribute9;
    }
    public String getAttribute10() {
        return attribute10;
    }
    public void setAttribute10(String attribute10) {
        this.attribute10 = attribute10;
    }
    @Override
    public String toString() {
        return "ExamPaper{" +
                "attribute1='" + attribute1 + '\'' +
                ", attribute2='" + attribute2 + '\'' +
                ", attribute3='" + attribute3 + '\'' +
                ", attribute4='" + attribute4 + '\'' +
                ", attribute5='" + attribute5 + '\'' +
                ", attribute6='" + attribute6 + '\'' +
                ", attribute11='" + attribute11 + '\'' +
                ", attribute7='" + attribute7 + '\'' +
                ", attribute8='" + attribute8 + '\'' +
                ", attribute9='" + attribute9 + '\'' +
                ", attribute10='" + attribute10 + '\'' +
                '}';
    }
}
public class Client {
    public static void main(String[] args) {
        ExamPaper examPaper = new ExamPaper();
        examPaper.setAttribute1("1");
        examPaper.setAttribute4("4");
        examPaper.setAttribute2("2");
        examPaper.setAttribute5("50");
        System.out.println("源对象:"+examPaper.toString());
        ExamPaper copy = (ExamPaper)BeanUtils.copy(examPaper);
        System.out.println("copy对象:"+copy);
    }
}

2、通用实现:

抽象原型实现
public interface IPrototype<T> {
    T clone();
}
具体原型实现
public class ConcretePrototype implements IPrototype {
    private int age;
    private String name;
    private List<String> hobbies;
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List<String> getHobbies() {
        return hobbies;
    }
    public void setHobbies(List<String> hobbies) {
        this.hobbies = hobbies;
    }
    @Override
    public String toString() {
        return "ConcretePrototype{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", hobbies=" + hobbies +
                '}';
    }
    //这里可以使用set赋值,也可以模仿简单实现内通过反射来赋值
    @Override
    public ConcretePrototype clone() {
        ConcretePrototype concretePrototype = new ConcretePrototype();
        concretePrototype.setAge(age);
        concretePrototype.setName(name);
        return concretePrototype;
    }
}
public class Client {
    public static void main(String[] args) {
        ConcretePrototype concretePrototype = new ConcretePrototype();
        concretePrototype.setName("wangzx");
        concretePrototype.setAge(10);
        List<String> h = new ArrayList<>();
        h.add("打球");
        h.add("看电影");
        concretePrototype.setHobbies(h);
        System.out.println("源对象" + concretePrototype.toString());

        ConcretePrototype clone = concretePrototype.clone();
        clone.setName("lisi");
        h.add("上网");
        clone.setHobbies(h);

        System.out.println("克隆后的对象:" + clone.toString());
        //源对象名没有改变???
        System.out.println("克隆对象改名后源对象名:" + concretePrototype.toString());
        //源对象爱好改变
        System.out.println("克隆对象新增爱好后源对象爱好:" + concretePrototype.toString());
    }
}

优点:java自带的原型模式是基于内存二进制流的拷贝,比直接new一个对象性能上提升了许多。
可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份并将其状态保存起来,简化了创建过程
缺点:必须配备克隆或者可拷贝的方法,当对已有类进行改造的时候,需要修改代码,违背了开闭原则,深拷贝、浅拷贝需要运用得当

相关文章

  • Java架构师课程

    Java架构班开学典礼 Spring中常用的设计模式概述及工厂模式详解 单例模式及原型模式单例模式及原型模式单例模...

  • 原型模式详解

    不通过new(构造方法)创建对象,通过clone,或者copy的操作创建对象使用场景:1、类初始化消耗资源较多2、...

  • Python列表append、extend、+、+=详解

    Python列表append、extend、+、+=详解 append方法 原型: 原型解析: 从原型可以看出, ...

  • 廖雪峰JS小记

    (function(){})() 原型,原型链 浅谈Js原型的理解JS 原型与原型链终极详解 对象 对象:一种无序...

  • 第3章 创建型模式-原型模式

    一、原型模式简介 二、原型模式的优点 ■ 三、原型模式的使用场景 ■ 四、原型模式的实例

  • 设计模式之原型模式(Prototype 模式)

    引入原型模式 原型模式的实例 为什么需要使用原型模式 引入原型模式 如果读者很熟悉javascript的话,对原型...

  • 初始设计模式之原型模式

    原型模式是什么? 原型模式怎么用?浅拷贝深拷贝 原型模式再理解 一、原型模式是什么? ​ 原型模式是一种创建型设计...

  • 设计模式之原型模式(创建型)

    [TOC] 模式定义 原型模式(Prototype Pattern):原型模式是提供一个原型接口,提供原型的克隆,...

  • Javascript(三)之原型继承理解

    进阶路线 3 原型继承 3.1 优秀文章 最详尽的 JS 原型与原型链终极详解 一 最详尽的 JS 原型与原型链终...

  • 原型模式C++

    原型模式,用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 原型模式结构图 原型模式基本代码 原型...

网友评论

      本文标题:原型模式详解

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