Code Ease Code Ease
  • 个人博客网站 (opens new window)
  • 好用的工具网站 (opens new window)
  • Java核心基础
  • 框架的艺术
  • 分布式与微服务
  • 开发经验大全
  • 设计模式
  • 版本新特性
数据库系列
大数据+AI
  • xxl-job
运维与Linux
  • 基于SpringBoot和BootStrap的论坛网址
  • 基于VuePress的个人博客网站
  • 基于SpringBoot开发的小功能
  • 做一个自己的IDEA插件
程序人生
关于我
  • 分类
  • 标签
  • 归档

神秘的鱼仔

你会累是因为你在走上坡路
  • 个人博客网站 (opens new window)
  • 好用的工具网站 (opens new window)
  • Java核心基础
  • 框架的艺术
  • 分布式与微服务
  • 开发经验大全
  • 设计模式
  • 版本新特性
数据库系列
大数据+AI
  • xxl-job
运维与Linux
  • 基于SpringBoot和BootStrap的论坛网址
  • 基于VuePress的个人博客网站
  • 基于SpringBoot开发的小功能
  • 做一个自己的IDEA插件
程序人生
关于我
  • 分类
  • 标签
  • 归档
服务器
  • 适配器模式详解与应用
  • 迭代器模式:理解与实践
  • 模板方法设计模式理论与应用
  • 快速理解工厂方法模式,及其在源码中的应用
  • 详解单例模式及其在Sping中的最优实践
  • 快速理解原型模式,及其在源码中的应用
    • (一)什么是原型模式
    • (二)原型模式的简单例子
    • (三)基于管理器的原型模式
    • (四)原型模式在源码中的应用
    • (五)总结
  • 快速理解建造者模式,及其在JDK源码中的应用
  • 最实用的设计模式:策略模式的快速理解
  • 快速理解装饰者模式,及其在JDK源码中的应用
  • 快速理解观察者模式,原来它还有这么多其他名字
  • 设计模式
CodeEase
2023-10-23
目录

快速理解原型模式,及其在源码中的应用

作者:鱼仔
博客首页: codeease.top (opens new window)
公众号:Java鱼仔

# (一)什么是原型模式

在正常的开发过程中,百分之99的对象实例都是通过new进行创建的,但是在实际的场景中,还是存在一些不通过new生成对象实例的应用场景。

比如:需要生成大量类似的对象实例时,如果都通过new去创建,性能并不好。

又比如:通过很复杂的方式生成了一个对象,现在要再创建出一个类似的对象出来。

上面的两种应用场景都可以通过“拷贝”这个动作来实现,这种根据一个已有的原型对象,拷贝生成新的对象的方式,就是设计模式中的原型模式(prototype)。

在Java中,可以通过Cloneable接口和clone方法很好地实现原型模式。

# (二)原型模式的简单例子

首先通过一个简单的例子让大家快速了解原型模式。

过年的时候公司给每个人发了一份邮件,这个邮件里除了署名和入职年份不一样以外,其他的内容都是相同的。比如:张三,这是你入职的第一年,祝你新年快乐XXXXX;李四,这是你入职的第二年,祝你新年快乐XXXXX。

这里的每一份邮件都可以理解为一个对象,而所有的对象实例都是相似的对象实例,因此就可以实用原型模式来拷贝生成这些重复的对象。

首先创建一个邮件对象,需要实现Cloneable接口:

public class Mail implements Cloneable{
    private String name;
    private String content;
    private Integer years;
    Mail(String name,String content,Integer years){
        this.name = name;
        this.content = content;
        this.years = years;
        System.out.println("对象创建成功");
    }
    private void showMail(){
        System.out.println(name+",这是你入职的第"+years+"年,"+content);
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        System.out.println("拷贝成功");
        return super.clone();
    }

    public void setContent(String content) {
        this.content = content;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setYears(Integer years) {
        this.years = years;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

接下来在使用的时候先通过new创建一个基础对象实例,其他的均通过clone进行拷贝:

public static void main(String[] args) throws CloneNotSupportedException {
    Mail mail = new Mail("张三", "祝你新年快乐XXXXXX", 1);
    mail.showMail();
    Mail cloneMail = (Mail) mail.clone();
    cloneMail.setName("李四");
    cloneMail.setYears(2);
    mail.showMail();
}
1
2
3
4
5
6
7
8

这样一个简单的原型模式就实现了。

# (三)基于管理器的原型模式

上面的例子可以增加对原型模式的理解,在实际开发中,更常用的是使用一个管理器去管理原型对象,可以在管理器类中通过一个HashMap保存原型对象。以水果店为例子。

首先定义了一个接口叫做Fruit,里面有两个方法:,shape方法用于展示水果的外观,createFruit方法用于通过克隆创建原型对象实例。

public interface Fruit extends Cloneable{
    void shape();
    Object createFruit() throws Exception;
}
1
2
3
4

接着定义管理器,管理器由HashMap进行管理,提供注册和创建实例的功能:

public class FruitManager {
    private HashMap<String,Fruit> managerMap = new HashMap<>();
    public void register(String name,Fruit fruit){
        managerMap.put(name,fruit);
    }
    public Fruit create(String name) throws Exception{
        Fruit fruit = managerMap.get(name);
        return (Fruit) fruit.createFruit();
    }
}
1
2
3
4
5
6
7
8
9
10

下一步就是定义两个具体的对象,需要注意的是createFruit()方法使用了clone()进行拷贝:

public class Apple implements Fruit{
    @Override
    public void shape() {
        System.out.println("苹果是红色的圆形水果");
    }
    @Override
    public Object createFruit() throws Exception {
        return super.clone();
    }
}

public class Orange implements Fruit{
    @Override
    public void shape() {
        System.out.println("橘子是黄色的圆形水果");
    }
    @Override
    public Object createFruit() throws Exception{
        return super.clone();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

最后写一个测试方法:

public static void main(String[] args) throws Exception {
    FruitManager manager = new FruitManager();
    //注册到管理器中
    manager.register("apple",new Apple());
    manager.register("orange",new Orange());
    //通过create方法不断拷贝新的对象
    Fruit apple = manager.create("apple");
    apple.shape();
    Fruit orange = manager.create("orange");
    orange.shape();
}
1
2
3
4
5
6
7
8
9
10
11

# (四)原型模式在源码中的应用

其实在很多地方都用到了原型模式,比如最常用的ArrayList,同样定义了clone方法供调用者进行拷贝。

抛去Cloneable相关的接口,一些对象之间的复制操作也是原型模式的实践,比如Spring里BeanUtils.copyProperties()这个方法,同样实现了根据一个已有的原型对象,拷贝生成新的对象。

# (五)总结

本章内容主要通过两个例子讲解了原型模式的概念以及应用,我是鱼仔,我们下期再见!

上次更新: 2025/02/18, 11:30:08
详解单例模式及其在Sping中的最优实践
快速理解建造者模式,及其在JDK源码中的应用

← 详解单例模式及其在Sping中的最优实践 快速理解建造者模式,及其在JDK源码中的应用→

最近更新
01
AI大模型部署指南
02-18
02
半个月了,DeepSeek为什么还是服务不可用
02-13
03
Python3.9及3.10安装文档
01-23
更多文章>
Theme by Vdoing | Copyright © 2023-2025 备案图标 浙公网安备33021202002405 | 浙ICP备2023040452号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式