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

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

模式定义与特点

  • 定义

    用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。比如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
【设计模式】原型模式
【设计模式】原型模式
|
1月前
|
设计模式 Java 关系型数据库
23种设计模式 —— 原型模式【克隆羊、浅拷贝、深拷贝】
23种设计模式 —— 原型模式【克隆羊、浅拷贝、深拷贝】
|
1月前
|
设计模式 Java
Java设计模式【五】:原型模式
Java设计模式【五】:原型模式
20 0
|
7月前
|
设计模式 Java 关系型数据库
认真学习设计模式之原型模式(Prototype Pattern)
认真学习设计模式之原型模式(Prototype Pattern)
40 0
认真学习设计模式之原型模式(Prototype Pattern)
|
1月前
|
设计模式 存储
二十三种设计模式全面解析-原型模式进阶之原型管理器:集中管理对象原型的设计模式之道
二十三种设计模式全面解析-原型模式进阶之原型管理器:集中管理对象原型的设计模式之道
|
1月前
|
设计模式 Java
【设计模式系列笔记】原型模式
原型模式(Prototype Pattern)是一种创建型设计模式,其主要目的是通过复制现有对象来创建新对象,而无需知道其具体类型。这种模式属于对象创建型模式,通过克隆来避免使用new关键字创建对象,提高性能和降低系统的耦合度。
36 6
|
1月前
|
设计模式 Java
小谈设计模式(10)—原型模式
小谈设计模式(10)—原型模式
|
1月前
|
设计模式 Java
23种设计模式,原型模式的概念优缺点以及JAVA代码举例
【4月更文挑战第10天】原型模式是一种创建型设计模式,它允许通过复制现有对象来创建新的对象,而无需知道如何创建的细节。这种模式的核心思想是基于一个原型实例,通过复制这个原型来创建新的对象
29 7
|
1月前
|
设计模式 Java
设计模式之原型模式
设计模式之原型模式
|
1月前
|
设计模式 存储 JSON
Java设计模式-原型模式
原型模式也是创建对象的一种方式,它一般用在这样的场景:系统中存在大量相同或相似对象的创建问题,如果用传统的构造函数来创建对象,会比较复杂而且耗费资源。这个时候使用原型模式的克隆方式,能够节省不少时间。比如Java 类中提供的`Object clone()`就是原型模式的应用。
34 1
Java设计模式-原型模式