深入Java设计模式之原型模式

简介: 深入Java设计模式之原型模式

原型模式的核心是如何实现拷贝

public class PrototypeClass implements Cloneable
{
    public PrototypeClass clone()
    {
        PrototypeClass prototypeClass = null;
        try
        {
            prototypeClass = (PrototypeClass) super.clone();
        } catch (CloneNotSupportedException exception)
        {
            exception.printStackTrace();
        }
        return prototypeClass;
    }
}

 

 

package com.lzhsite.technology.deepcopy;
/**
 * 浅拷贝是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象。
 * 深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。举例来说更加清楚:对象A1中包含对B1的引用,
 * B1中包含对C1的引用。浅拷贝A1得到A2,A2 中依然包含对B1的引用,B1中依然包含对C1的引用。深拷贝则是对浅拷贝的递归,
 * 深拷贝A1得到A2,A2中包含对B2(B1的copy)的引用,B2 中包含对C2(C1的copy)的引用。
 * 若不对clone()方法进行改写,则调用此方法得到的对象即为浅拷贝,下面我们着重谈一下深拷贝
 * 
 * 注意:深复制只针自定义对象,基本数据类型的对象默认都是深复制
 */
class Professor0 implements Cloneable {
    String name;
    int age;
    Professor0(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class Student0 implements Cloneable {
    String name;// 常量对象。
    int age;
    Professor0 p;// 学生1和学生2的引用值都是一样的。
    Student0(String name, int age, Professor0 p) {
        this.name = name;
        this.age = age;
        this.p = p;
    }
    public Object clone() {
        Student0 o = null;
        try {
            o = (Student0) super.clone();
        } catch (CloneNotSupportedException e) {
            System.out.println(e.toString());
        }
        return o;
    }
}
public class ShallowCopy {
    public static void main(String[] args) {
        Professor0 p = new Professor0("wangwu", 50);
        Student0 s1 = new Student0("zhangsan", 18, p);
        Student0 s2 = (Student0) s1.clone();
        s2.p.name = "lisi";
        s2.p.age = 30;
        s2.name = "z";
        s2.age = 45;
        System.out.println("学生s1的姓名:" + s1.name + "\n学生s1教授的姓名:" + s1.p.name + "," + "\n学生s1教授的年纪" + s1.p.age);// 学生1的教授
    }
}
预想输出:
学生s1的姓名:zhangsan
学生s1教授的姓名:wangwu,
学生s1教授的年纪50
结果输出:
学生s1的姓名:zhangsan
学生s1教授的姓名:lisi,
学生s1教授的年纪30

下面来通过一个实例来理解下深浅拷贝:

public class Client {
  public static void main(String args []) throws CloneNotSupportedException {
    DogClone dogClone = new DogClone();
    dogClone.legCounts = 3;
    System.out.println("原来的克隆狗腿数量:"+dogClone.legCounts);
    System.out.println("原来的普通狗腿的数量:"+dogClone.dog);//Dog的toString方法返回的值。
    DogClone dogClone1 = (DogClone)dogClone.clone();
    dogClone1.legCounts=2 ;
     Dog dog = dogClone1.dog;
     dog.changeLegCounts();
     System.out.println("克隆后原来狗腿数量:"+dogClone.legCounts);
     /**
      * 出现的结果是:8
      * 原因很简单就是dog是一个引用,改变一个对象的话,会改变另一个对象。
      */
     System.out.println("克隆后原来普通狗的数量:"+ dogClone.dog);
     System.out.println("克隆后克隆狗腿的数量:"+ dogClone1.legCounts);
     /**
      *改变源:改变了自身dogClone.dog,影像了对象dogClone.dog 的值,
      */
     System.out.println("克隆后普通狗的数量:"+ dogClone1.dog);
  }
}
/**
 * 未实现了克隆方法的类和实现克隆方法的类做比较
 *
 */
public class Dog {
  /**
   * 狗腿条数
   */
  public int legCounts;
  public Dog(int legCounts) {
    this.legCounts = legCounts;
  }
  /**
   * 改变狗的腿数量
   */
  public void changeLegCounts(){
    this.legCounts *=2;
  }
  public String toString () {
    return Integer.toString(this.legCounts);
  }
}
public class DogClone implements Cloneable {
  /**
   * 狗腿条数
   */
  public int legCounts;
  /**
   * 初始化一个狗
   */
  Dog dog = new Dog(4);
  @Override
  protected DogClone clone() throws CloneNotSupportedException {
    return (DogClone)super.clone();
  }
}

输出结果:

    原来的克隆狗腿数量:3

    原来的普通狗腿的数量:4

    克隆后原来狗腿数量:3

    克隆后原来普通狗的数量:8

    克隆后克隆狗腿的数量:2

    克隆后普通狗的数量:8

让Doc实现Cloneable接口后

/**
 * 该类是没有实现克隆方法的类和实现克隆方法的类做比较
 *
 */
public class Dog implements Cloneable{
  /**
   * 狗腿条数
   */
  public int legCounts;
  public Dog(int legCounts) {
    this.legCounts = legCounts;
  }
  /**
   * 改变狗的腿数量
   */
  public void changeLegCounts(){
    this.legCounts *=2;
  }
  @Override
  public Dog clone() throws CloneNotSupportedException {
    return (Dog)super.clone();
  }
  public String toString () {
    return Integer.toString(this.legCounts);
  }
}

输出结果:

    原来的克隆狗腿数量:3

    原来的普通狗腿的数量:4

    克隆后原来狗腿数量:3

    克隆后原来普通狗的数量:4

    克隆后克隆狗腿的数量:2

    克隆后普通狗的数量:8

对原型模式的总结:


目录
相关文章
|
5月前
|
设计模式 JavaScript Java
【设计模式】【创建型模式】原型模式(Prototype)
一、入门 什么是原型模式? 原型模式(Prototype Pattern)是一种创建型设计模式,它通过复制现有对象来创建新对象,而不是通过实例化类。 原型模式的核心是克隆(Clone),即通过复制现有
181 15
|
5月前
|
设计模式 缓存 安全
【高薪程序员必看】万字长文拆解Java并发编程!(8):设计模式-享元模式设计指南
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发编程中的经典对象复用设计模式-享元模式,废话不多说让我们直接开始。
119 0
|
7月前
|
设计模式 Java 数据安全/隐私保护
Java 设计模式:装饰者模式(Decorator Pattern)
装饰者模式属于结构型设计模式,允许通过动态包装对象的方式为对象添加新功能,提供比继承更灵活的扩展方式。该模式通过组合替代继承,遵循开闭原则(对扩展开放,对修改关闭)。
|
9月前
|
设计模式 存储 Java
「全网最细 + 实战源码案例」设计模式——原型模式
原型模式(Prototype Pattern)是一种创建型设计模式,通过复制现有对象来创建新对象,适用于创建成本高或复杂的对象场景。其核心思想是“克隆”,避免直接实例化类。结构上分为抽象原型类、具体原型类和客户端。优点包括减少对象创建成本、隐藏复杂性、简化实例创建;缺点是处理循环引用的复杂对象时较为麻烦。实现步骤为定义原型类、重写`clone()`方法并调用。注意事项包括浅拷贝与深拷贝的区别及`Cloneable`接口的使用。
139 20
|
11月前
|
设计模式 消息中间件 搜索推荐
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
180 6
|
11月前
|
设计模式 Java 数据库连接
Java编程中的设计模式:单例模式的深度剖析
【10月更文挑战第41天】本文深入探讨了Java中广泛使用的单例设计模式,旨在通过简明扼要的语言和实际示例,帮助读者理解其核心原理和应用。文章将介绍单例模式的重要性、实现方式以及在实际应用中如何优雅地处理多线程问题。
150 4
|
设计模式 监控 算法
Java设计模式梳理:行为型模式(策略,观察者等)
本文详细介绍了Java设计模式中的行为型模式,包括策略模式、观察者模式、责任链模式、模板方法模式和状态模式。通过具体示例代码,深入浅出地讲解了每种模式的应用场景与实现方式。例如,策略模式通过定义一系列算法让客户端在运行时选择所需算法;观察者模式则让多个观察者对象同时监听某一个主题对象,实现松耦合的消息传递机制。此外,还探讨了这些模式与实际开发中的联系,帮助读者更好地理解和应用设计模式,提升代码质量。
Java设计模式梳理:行为型模式(策略,观察者等)
|
11月前
|
设计模式 JavaScript Java
Java设计模式:建造者模式详解
建造者模式是一种创建型设计模式,通过将复杂对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表示。本文详细介绍了建造者模式的原理、背景、应用场景及实际Demo,帮助读者更好地理解和应用这一模式。
531 0
|
存储 设计模式 安全
Java设计模式-备忘录模式(23)
Java设计模式-备忘录模式(23)
123 3
|
设计模式 存储 算法
Java设计模式-命令模式(16)
Java设计模式-命令模式(16)
165 2