设计模式之原型模式

简介: 复制粘贴功能我们都用过,我们可以把一个文件从一个地方复制到另外一个地方,复制完成之后这个文件和之前的文件也没有一点差别,这就是原型模式的思想:首先创建一个实例,然后通过这个实例去拷贝创建新的实例。这篇文章就好好地分析一下原型模式。

一、认识原型模式


1、概念


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

我们拿电脑中复制粘贴的例子来演示一下原型模式.

v2-44f1296e4007dab270c578eb31b7107d_1440w.jpg

上面这张图已经很明显了,首先我们需要一个文件,这个文件一定要有可以被克隆的功能,那么我们创建这个文件之后,就可以通过它克隆出无数个。


2、java类图分析


下面我们再从类图的角度来分析一下:

v2-7b5893163be6e10425d6264c08ee166e_1440w.jpg

首先我们可以看到一共有三个角色:


(1)客户(Client)角色:客户类提出创建对象的请求;也就是我们用户使用复制粘贴的功能。


(2)抽象原型(Prototype)角色:此角色定义了的具体原型类所需的实现的方法。也就是定义一个文件,说明一下它有被克隆复制的功能。


(3)具体原型(Concrete Prototype)角色:实现抽象原型角色的克隆接口。就是我们的文件实现了可以被复制的功能。


我们会发现其实原型模式的核心就是Prototype(抽象原型),他需要继承Cloneable接口,并且重写Object类中的clone方法才能有复制粘贴的功能。


3、分类


既然我们知道原型模式的核心就是拷贝对象,那么我们能拷贝一个对象实例的什么内容呢?这就要区分深拷贝和浅拷贝之分了。


(1)浅拷贝:我们只拷贝对象中的基本数据类型(8种),对于数组、容器、引用对象等都不会拷贝


(2)深拷贝:不仅能拷贝基本数据类型,还能拷贝那些数组、容器、引用对象等,

下面我们就使用代码去实现一下原型模式。这里实现的是不仅有基本数据类型,还有数组和容器,所以实现的是深拷贝。


二、代码实现原型模式


第一步:定义抽象原型

//定义一个文件抽象原型
public class Prototype implements Cloneable{
    private Integer fileid;
    private String filename;
    private Map<String, Double> scores;
    //getter和setter方法
    //有参构造方法
    //toString方法
    @Override
    protected Prototype clone()  {
        Prototype filePrototype = null;
        try {
            //有了下面这句话,基本类型就能克隆了
            filePrototype = (FilePrototype) super.clone();
            //下面要对每一个复杂对象进行分别克隆
            filePrototype.scores = (Map<String, Double>) ((HashMap)this.scores).clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return filePrototype;
    }    
}

第二步:定义具体原型

public class FileConcretePrototype extends Prototype{
    public ConcretePrototype(Integer fileid, String filename,Map<String, Double> scores){
        System.out.println("*********我是构造方法***********"); 
        super(fileid, filename, scores);
    }
    public void show(){  
        System.out.println("====文件信息======="); 
        System.out.println("文件名:"+this.getFilename()); 
        System.out.println("文件号:"+this.getFileid()); 
        System.out.println("文件打分:"+this.getScores()); 
    } 
}

第三步:定义用户去模拟过程

public class User {
    public static void main(String[] args) {
        String fileName="重要文件";
        int fileId=1;
        Map<String, Double> fileScores=new HashMap<String, Double>();
        fileScores.put("张三", 99.99);
        //第一步创建出一个实例对象
        ConcretePrototype fileA=new ConcretePrototype(fileId, fileName, fileScores);
        //第二步克隆出来几个
        ConcretePrototype fileB=(ConcretePrototype) fileA.clone();
        ConcretePrototype fileC=(ConcretePrototype) fileA.clone();
        //第三步:输出一下克隆出来的对象是否有变化
        fileB.show();
        fileC.show();
    }
}
//输出是:
/*
*********我是构造方法***********
=========文件信息=============
文件名:重要文件
文件号:1
文件打分:{张三=99.99}
=========文件信息=============
文件名:重要文件
文件号:1
文件打分:{张三=99.99}
*/

我们可以看到,克隆出来的两个文件和之前的文件是一样的,而且我们实现了深拷贝,对于数组、引用等对象同样的适用。


三、分析原型模式


对于原型模式有几个问题需要我们去注意一下


1、克隆对象不会调用构造方法


从上面的输出其实我们也可以发现,构造方法只在一开始我们创建原型的时候输出了,fileB和fileC都没有调用构造方法,这是因为执行clone方法的时候是直接从内存中去获取数据的,在第一次创建对象的时候就会把数据在内存保留一份,克隆的时候直接调用就好了


2、访问权限对原型模式无效


原理也很简单,我们是从内存中直接复制的,所以克隆起来也会直接无视,复制相应的内容就好了。


3、使用场景


(1)当我们的类初始化需要消耗很多的资源时,就可以使用原型模式,因为我们的克隆不会执行构造方法,避免了初始化占有的时间和空间。

(2)一个对象被其她对象访问,并且能够修改时,访问权限都无效了,什么都能修改。


相关文章
|
7月前
|
设计模式 安全 Java
面向对象编程的精髓:Java设计模式 - 原型模式(Prototype)完全参考手册
【4月更文挑战第7天】原型模式是OOP中的创建型设计模式,用于通过复制现有实例创建新实例,尤其适用于创建成本高或依赖其他对象的情况。它包括Prototype接口、ConcretePrototype实现和Client客户端角色。优点是性能优化、避免子类化和动态增加产品族。实现包括定义原型接口、实现具体原型和客户端调用克隆方法。最佳实践涉及确保克隆正确性、选择深拷贝或浅拷贝及考虑线程安全。但需注意克隆方法管理、性能开销和循环引用等问题。在Java中,实现Cloneable接口和覆盖clone方法可实现原型模式。
85 4
|
7月前
|
设计模式 Java 关系型数据库
23种设计模式 —— 原型模式【克隆羊、浅拷贝、深拷贝】
23种设计模式 —— 原型模式【克隆羊、浅拷贝、深拷贝】
|
7月前
|
设计模式 安全 Java
【设计模式】原型模式
【设计模式】原型模式
|
3月前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑】设计模式——原型模式
对比原型模式和传统方式的实现思路、代码方案、优缺点,阐述原型模式的使用场景,以及深拷贝、浅拷贝等相关概念,并扩展原型模式在Spring源码中的应用。
【Java笔记+踩坑】设计模式——原型模式
|
3月前
|
设计模式 Java
Java设计模式-原型模式(3)
Java设计模式-原型模式(3)
Java设计模式-原型模式(3)
|
5月前
|
设计模式
iLogtail设计模式问题之iLogtail中的原型模式是什么
iLogtail设计模式问题之iLogtail中的原型模式是什么
iLogtail设计模式问题之iLogtail中的原型模式是什么
|
5月前
|
设计模式 JavaScript
js设计模式【详解】—— 原型模式
js设计模式【详解】—— 原型模式
53 6
|
6月前
|
设计模式 Java
Java设计模式之原型模式详解
Java设计模式之原型模式详解
|
6月前
|
设计模式
原型模式-大话设计模式
原型模式-大话设计模式
|
6月前
|
设计模式 Java Spring
设计模式——原型模式
设计模式——原型模式