JAVA设计模式(三)-原型

JAVA设计模式(三)-原型

本篇文章主要讲下java 创建型设计模式中的原型模式.

何谓原型模式: 简单来说就是 将一个对象作为原型,通过对其进行复制而克隆出多个和原型类似的新实例。

使用原型模式,就可以简化实例化的过程, 不必依赖于构造函数或者new关键字.

由于java 提供了clone方法, 原型设计模式的实现就很简单了.

原型模式的要素:

  1. 原型接口(Prototype Interface): 定义了克隆方法的接口.该方法用于复制现有对象并创建新对象。
  2. 原型类(Concrete Prototype Class): 实现了克隆方法,来复制自身

1: 原型类

具体的实现如下:

java 复制代码
package com.zh.xpose;

import java.util.List;

/**
 * @Author: zh
 * @Time: 23-12-22.
 * @Email:
 * @Describe:
 */
public class ConcretePrototype implements Cloneable{
    private String name;
    private List<String> fields;

    public ConcretePrototype(String name,List<String> fields) {
        System.out.println("原型创建成功");
        this.name =name;
        this.fields =fields;
    }

    public String getName() {
        return name;
    }

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

    public List<String> getFields() {
        return fields;
    }

    public void setFields(List<String> fields) {
        this.fields = fields;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        System.out.println("原型复制成功");
        return (ConcretePrototype)super.clone();
    }
}
java 复制代码
public class JavaTest {
    public static void main(String[] args) {		
		ArrayList<String> list = new ArrayList<>();
        list.add("age");
        list.add("sex");
        ConcretePrototype concretePrototype = new ConcretePrototype("person",list);
        ConcretePrototype clone = null;
        try {
            clone= (ConcretePrototype) concretePrototype.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        System.out.println(concretePrototype==clone);
        System.out.println(concretePrototype.getName() == clone.getName());
        System.out.println(concretePrototype.getFields() == clone.getFields());
        
    }
}

输出如下:

java 复制代码
exclude patterns:
原型创建成功
原型复制成功
false
true
true

2: 浅克隆和深克隆

浅克隆只会复制原型对象本身,而不会复制它所引用的对象。也就是说,克隆对象和原型对象会共享引用对象。如果原型对象中的引用对象发生改变,克隆对象中的引用对象也会发生改变。

深克隆会复制原型对象以及它所引用的对象。也就是说,克隆对象和原型对象拥有各自独立的引用对象。无论原型对象中的引用对象是否发生改变,克隆对象中的引用对象都不会受到影响。

关于浅克隆:

验证如下:

java 复制代码
		concretePrototype.setName("test111");
        list.add("第三个了");
        concretePrototype.setFields(list);
        System.out.println(concretePrototype.getName()+"  "+clone.getName());
        System.out.println(concretePrototype.getFields().size()+"  "+clone.getFields().size());

可以看到 当原型类中的list 发生变更时, clone同时发生了变更.

java 复制代码
test111  person
3  3

实现深克隆的方式有两种: 通过实现Cloneable接口和通过序列化.

这里通过修改上面的实现类中的clone方法,来实现深克隆.

java 复制代码
package com.zh.xpose;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author: zh
 * @Time: 23-12-22.
 * @Email:
 * @Describe:
 */
public class ConcretePrototype implements Cloneable{
    private String name;
    private List<String> fields;

    public ConcretePrototype(String name,List<String> fields) {
        System.out.println("原型创建成功");
        this.name =name;
        this.fields =fields;
    }

    public String getName() {
        return name;
    }

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

    public List<String> getFields() {
        return fields;
    }

    public void setFields(List<String> fields) {
        this.fields = fields;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        System.out.println("原型复制成功");
        ConcretePrototype clone = (ConcretePrototype) super.clone();
        clone.setName(new String(name));
        clone.setFields(new ArrayList<>(fields));
        return clone;
    }
}

重新执行验证代码 ,结果输出如下:

arduino 复制代码
原型创建成功
原型复制成功
false
false
false
test111  person
3  2
相关推荐
码匠许师傅13 分钟前
【C++ 面试真题】聊聊 C++ 的虚函数和多态
java·c++·面试
chuan.bai40 分钟前
Java RAG 实战(第 8 篇):Spring Boot RAG 查询 API
java·spring boot·贪心算法
FlyWIHTSKY41 分钟前
idea中集成claude功能
java·ide·人工智能·intellij-idea·cloudera
Java成神之路-1 小时前
Spring AI 统一结构化返回:ChatModel / ChatClient 两种实现方式
java·springaialibaba
Mr. zhihao1 小时前
深度解析:为什么Java序列化需要搭配ByteArrayOutputStream?IO装饰器模式的精妙设计
java·开发语言·装饰器模式
存在morning1 小时前
【Python 开发实践 一】Python vs Go vs Java 三门语言对比
java·python·golang
vx-程序开发1 小时前
springboot旅游推介平台---附源码24175
java·spring boot·python·spring cloud·eclipse·django·idea
艾莉丝努力练剑1 小时前
【QT:解决问题】Qt5Core.dll:无法定位程序输入点
java·开发语言·qt·学习·面试
小蒜学长2 小时前
“喵汪联盟”宠物领养系统的设计与实现(代码+数据库+LW)
java·spring boot·后端·宠物
程序员黑豆2 小时前
Java字符串常量池完全指南:原理、intern()方法与性能优化最佳实践
java·前端·ai编程