原型设计模式

        原型设计模式(Prototype Design Pattern)是面向对象设计模式的一种,属于创建型设计模式,其主要目的是为了创建新对象提供了一种较为灵活的方式,特别适用于那些创建新对象的成本比较高或者复杂度较大的场景。原型模式允许我们通过复制一个现有对象(即原型)来创建新对象,而不是每次都通过new关键字来调用构造函数创建新的实例。

在原型模式中,通常包含以下几个关键角色:

  1. Prototype Interface(原型接口): 定义了一个克隆自身的操作,通常是 clone() 方法,它是所有具体原型类都需要实现的接口。

  2. Concrete Prototype(具体原型类): 实现了原型接口,并且添加了维持内部状态足够的信息以便能够克隆自身。当调用 clone() 方法时,会创建一个与原对象状态相同或部分相同的新对象。

  3. Client(客户端): 使用原型接口来请求克隆对象,而不需要关心具体的实现细节。

原型模式的核心优势在于:

  • 提供了一种独立于类的创建对象的方法,避免了直接使用new操作符带来的约束。
  • 可以动态地指定要创建的对象类型,使得系统更加灵活。
  • 当创建新对象的成本较大时(比如初始化资源消耗大),通过复制已有的原型对象,能显著提高性能。
  • 支持深克隆(Deep Clone),可以完整复制对象及其引用对象的所有状态。

        在Java中,实现原型模式一般会重写 Object 类自带的 clone() 方法,或者实现 Cloneable 接口并处理好浅克隆和深克隆的逻辑。如果涉及到复杂的数据结构或包含非基本类型的成员变量,则需要特别注意深克隆的实现,以免出现引用复制而非值复制的问题。

        在Java中实现原型模式,首先需要一个实现了Cloneable接口的实体类,然后重写Object类的clone()方法。以下是一个简单的Java示例:

import java.util.Date;

public class Employee implements Cloneable {
    private String name;
    private Date hireDate;

    public Employee(String name, Date hireDate) {
        this.name = name;
        this.hireDate = hireDate;
    }

    public String getName() {
        return name;
    }

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

    public Date getHireDate() {
        return hireDate;
    }

    public void setHireDate(Date hireDate) {
        this.hireDate = hireDate;
    }

    // 重写Object类的clone()方法,实现深克隆
    @Override
    public Object clone() throws CloneNotSupportedException {
        Employee clonedEmployee = (Employee) super.clone();
        // 如果对象包含复杂的成员变量,此处需要对它们也进行深克隆
        // 例如,Date是非基本类型,需要重新创建一个新的Date对象
        clonedEmployee.hireDate = (Date) this.hireDate.clone();
        return clonedEmployee;
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        try {
            Employee original = new Employee("John Doe", new Date());

            // 使用clone()方法创建新对象
            Employee cloned = (Employee) original.clone();

            System.out.println("Original Employee Name: " + original.getName());
            System.out.println("Cloned Employee Name: " + cloned.getName());

            // 修改原始对象的属性
            original.setName("Jane Doe");

            // 确认克隆对象不受原始对象更改的影响
            System.out.println("After changing original:");
            System.out.println("Original Employee Name: " + original.getName());
            System.out.println("Cloned Employee Name: " + cloned.getName());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

        在这个例子中,Employee 类实现了 Cloneable 接口,并重写了 clone() 方法以实现深克隆。客户端代码通过调用 clone() 方法来创建 Employee 对象的副本。当原始对象的属性发生变化时,克隆对象的属性保持不变,表明它们是独立的实体。需要注意的是,对于包含引用类型的成员变量,必须确保它们也被正确地克隆,以实现真正的深克隆。在本例中,Date 类本身已经实现了 clone() 方法,所以我们直接调用 hireDate.clone() 即可。

补充知识

        1、深拷贝与浅拷贝区别

        深拷贝和浅拷贝是计算机科学中对象复制时的两种概念,它们主要在处理复杂数据结构(如对象、数组或类实例)时有着显著的不同:

浅拷贝(Shallow Copy)

  • 浅拷贝是指复制对象时,仅仅复制对象本身,而不复制它所引用的对象。这意味着新旧对象指向相同的内存地址,因此对于对象中的基本类型字段(如int、char等),会各自拥有独立的副本;但对于对象引用类型字段(如数组、其他对象等),新旧对象共享同一份数据。
  • 如果其中一个对象改变了引用类型字段的内容,会影响到另一个对象,因为它们实际上是共享同一块内存区域。

深拷贝(Deep Copy)

  • 深拷贝则是指复制对象时,不仅复制对象本身,而且还递归地复制其引用的对象,直到所有的对象都是独立的实体,即每一个嵌套的对象都被复制一份放到内存的不同位置。
  • 如果对深拷贝后的对象进行修改,不会影响原对象及原对象引用的其他对象。换句话说,深拷贝会创建一个新的对象,并将原有对象的所有字段值一一复制过来,如果字段是对象类型,还会递归地复制该对象的所有字段,直至复制到基本类型字段为止。

举例来说,假设有一个对象A,其中有一个引用类型字段B,那么:

  • 浅拷贝:拷贝对象A得到对象A',此时A'的B字段与A的B字段指向同一个内存地址,修改A'的B字段会影响到A的B字段。
  • 深拷贝:拷贝对象A得到对象A',同时也会拷贝A的引用类型字段B,得到一个新的B',A'的B字段指向B',这样修改A'的B字段就不会影响到A的B字段。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值