设计模式轻松学【十七】原型模式

简介: 在有些系统中,存在大量相同或相似对象的创建问题,如果用传统的构造函数来创建对象,会比较复杂且耗时耗资源,用原型模式生成对象就很高效。就像孙悟空拔下猴毛轻轻一吹就变出很多孙悟空一样简单。

模式定义与特点

  • 定义

    用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。比如Ctrl+C,V就能快速的完成文件的复制粘贴

    也就是说我们通过原型模式可以通过复制(拷贝、克隆)原型对象快速的创建一个新的同类型的对象,而不需要提供专门的new()操作来完成对象的创建。

  • 问题由来

    当对象的构造函数非常复杂,在生成新对象的时候非常耗时间、耗资源的情况,我们可以使用原型模式来进行对象的创建

    当需要提供数据对象,同时又需要避免外部对数据对象进行修改。

  • 参与角色

    1. 抽象原型类:规定了具体原型对象必须实现的接口。
    2. 具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象。
  • 类结构图

    image.png

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

  • 实现Cloneable接口。Cloneable接口的作用只有一个,就是在运行时通知虚拟机可以安全地在实现了此接口的类上使用clone方法。虚拟机中,只有实现了这个接口的类才可以被拷贝,否则在运行时会抛出CloneNotSupportedException异常。
  • 重写Object类中的clone方法。clone方法作用是返回对象的一个拷贝,但是该方法的访问修饰符是protected类型的,其他包下的类无法调用该方法,因此我们一般会将Prototype类中的clone方法修改为public类型。

原型模式是一种比较简单的模式,也非常容易理解,实现一个接口,重写一个方法即完成了原型模式。在实际应用中,原型模式很少单独出现。经常与其他模式混用,他的原型类Prototype也常用抽象类来替代。

  • 案例实现

    • 抽象原型类

      abstract class Prototype implements Cloneable {
          
          @Override
          public Prototype clone() throws CloneNotSupportedException {
              return (Prototype)super.clone();
          }
          
          public abstract void show();
      }
    • 具体原型类

      class ConcretePrototype extends Prototype {
          public void show() {
              System.out.println("原型模式实现类");
          }
      }
    • 客户端调用
    public class Client {
        public static void main(String[] args){
            Prototype cp = new ConcretePrototype();
            for(int i=0; i< 10; i++){
                Prototype clonecp = cp.clone();
                clonecp.show();
            }
        }
    }

    原型模式的克隆分为浅克隆和深克隆,Java 中的 Object 类提供了浅克隆的 clone() 方法,具体原型类只要实现 Cloneable 接口就可实现对象的浅克隆。

深拷贝与浅拷贝

image.png

  • 浅拷贝:被拷贝对象的所有变量都含有与原对象相同的值,而且对其他对象的引用仍然是指向原来的对象。即浅拷贝只负责当前对象实例,对引用的对象不做拷贝。

    ArrayList<String> a = new ArrayList();
    ArrayList<String> b = a;
    //当修改a时,b的值同样会被修改,浅拷贝不适合在原型模式中使用
  • 深拷贝:

    被拷贝对象的所有的变量都含有与原来对象相同的值,除了那些引用其他对象的变量。那些引用其他对象的变量将指向一个被拷贝的新对象,而不再是原有那些被引用对象。即 深拷贝把要拷贝的对象所引用的对象也都拷贝了一次,而这种对被引用到的对象拷贝叫做间接拷贝。

    如果想要实现深拷贝,可以通过覆盖Object中的clone方法的方式,并且在clone方法内部,把该对象引用的其他对象也要clone一份 , 这就要求这个被引用的对象必须也要实现Cloneable接口并且实现clone方法。深拷贝存在一个问题,到底拷贝多深才算深拷贝?至于彻底深拷贝,几乎是不可能实现的。

总结

  • 对象之间相同或相似,即只是个别的几个属性不同的时候。
  • 对象的创建过程比较麻烦,但复制比较简单的时候。

    比如需要在一个循环体内创建对象,假如对象创建过程比较复杂或者循环次数很多的话,使用原型模式不但可以简化创建过程,而且可以使系统的整体性能提高很多。

  • 使用注意事项

    使用原型模式复制对象不会调用类的构造方法。因为对象的复制是通过调用Object类的clone方法来完成的,它直接在内存中复制数据,因此不会调用到类的构造方法。不但构造方法中的代码不会执行,甚至连访问权限都对原型模式无效。还记得单例模式吗?单例模式中,只要将构造方法的访问权限设置为private型,就可以实现单例。但是clone方法直接无视构造方法的权限,所以,单例模式与原型模式是冲突的,在使用时要特别注意。

目录
相关文章
|
1月前
|
设计模式 安全 Java
面向对象编程的精髓:Java设计模式 - 原型模式(Prototype)完全参考手册
【4月更文挑战第7天】原型模式是OOP中的创建型设计模式,用于通过复制现有实例创建新实例,尤其适用于创建成本高或依赖其他对象的情况。它包括Prototype接口、ConcretePrototype实现和Client客户端角色。优点是性能优化、避免子类化和动态增加产品族。实现包括定义原型接口、实现具体原型和客户端调用克隆方法。最佳实践涉及确保克隆正确性、选择深拷贝或浅拷贝及考虑线程安全。但需注意克隆方法管理、性能开销和循环引用等问题。在Java中,实现Cloneable接口和覆盖clone方法可实现原型模式。
|
1月前
|
设计模式 Java 关系型数据库
23种设计模式 —— 原型模式【克隆羊、浅拷贝、深拷贝】
23种设计模式 —— 原型模式【克隆羊、浅拷贝、深拷贝】
|
1月前
|
设计模式 安全 Java
【设计模式】原型模式
【设计模式】原型模式
|
1月前
|
设计模式 Java
Java设计模式【五】:原型模式
Java设计模式【五】:原型模式
21 0
|
1月前
|
设计模式 存储
二十三种设计模式全面解析-原型模式进阶之原型管理器:集中管理对象原型的设计模式之道
二十三种设计模式全面解析-原型模式进阶之原型管理器:集中管理对象原型的设计模式之道
|
4天前
|
设计模式 Java Spring
设计模式——原型模式
设计模式——原型模式
12 0
|
17天前
|
设计模式 存储 架构师
设计模式-值类型与引用类型、深拷贝与浅拷贝、原型模式详解
 如果拷贝的时候共享被引用的对象就是浅拷贝,如果被引用的对象也拷贝一份出来就是深拷贝。(深拷贝就是说重新new一个对象,然后把之前的那个对象的属性值在重新赋值给这个用户)
146 0
|
1月前
|
设计模式 测试技术 Go
[设计模式 Go实现] 创建型~ 原型模式
[设计模式 Go实现] 创建型~ 原型模式
|
1月前
|
设计模式 Java
【设计模式系列笔记】原型模式
原型模式(Prototype Pattern)是一种创建型设计模式,其主要目的是通过复制现有对象来创建新对象,而无需知道其具体类型。这种模式属于对象创建型模式,通过克隆来避免使用new关键字创建对象,提高性能和降低系统的耦合度。
41 6
|
1月前
|
设计模式 Java
23种设计模式,原型模式的概念优缺点以及JAVA代码举例
【4月更文挑战第10天】原型模式是一种创建型设计模式,它允许通过复制现有对象来创建新的对象,而无需知道如何创建的细节。这种模式的核心思想是基于一个原型实例,通过复制这个原型来创建新的对象
30 7