Java 设计模式以虹猫蓝兔的故事讲解原型模式

目录
  • 什么是原型模式
    • 优点
    • 缺点
    • 应用场景
  • 浅克隆
    • 代码实现
    • 总结
  • 深克隆
    • 代码实现
    • 总结

什么是原型模式

原型(Prototype)模式的定义如下: 用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。在这里,原型实例指定了要创建的对象的种类。用这种方式创建对象非常高效,根本无须知道对象创建的细节。例如,Windows 操作系统的安装通常较耗时,如果复制就快了很多。在生活中复制的例子非常多,这里不一一列举了。

优点

1、Java 自带的原型模式基于内存二进制流的复制,在性能上比直接 new 一个对象更加优良。

2、可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份,并将其状态保存起来,简化了创建对象的过程,以便在需要的时候使用(例如恢复到历史某一状态),可辅助实现撤销操作。

缺点

1、需要为每一个类都配置一个 clone 方法

2、clone 方法位于类的内部,当对已有类进行改造的时候,需要修改代码,违背了开闭原则。

3、当实现深克隆时,需要编写较为复杂的代码,而且当对象之间存在多重嵌套引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现起来会比较麻烦。因此,深克隆、浅克隆需要运用得当。

应用场景

在有些系统中,存在大量相同或相似对象的创建问题,如果用传统的构造函数来创建对象,会比较复杂且耗时耗资源,用原型模式生成对象就很高效,就像孙悟空拔下猴毛轻轻一吹就变出很多孙悟空一样简单。

浅克隆

案例:克隆虹猫

浅克隆一个虹猫,外表特征一样,但是只有一个灵魂。

克隆虹猫身体受到伤害,本体虹猫不受影响。

克隆虹猫精神受到伤害,本体虹猫也受到同样的伤害。

代码实现

虹猫灵魂状态类

这里声明了虹猫的灵魂状态

public class Hong {
    //虹猫的灵魂状态
    private String lh;
    Hong(String lh) {
        this.lh = lh;
    }
    Hong() {
    }

    public String getLh() {
        return lh;
    }

    public void setLh(String lh) {
        this.lh = lh;
    }

}

虹猫个体类

实现了Cloneable 接口,并且有虹猫的身体状态和灵魂状态等属性。

public class Qian implements Cloneable {
    private String shou;
    private String jiao;
    private String yan;
    private Hong hong;

    Qian() {
    }

    Qian(String shou, String jiao, String yan, Hong hong) {
        this.hong = hong;
        this.shou = shou;
        this.jiao = jiao;
        this.yan = yan;
    }

    public Qian clone() throws CloneNotSupportedException {
        return (Qian) super.clone();
    }

    public String getShou() {
        return shou;
    }

    public void setShou(String shou) {
        this.shou = shou;
    }

    public String getJiao() {
        return jiao;
    }

    public void setJiao(String jiao) {
        this.jiao = jiao;
    }

    public String getYan() {
        return yan;
    }

    public void setYan(String yan) {
        this.yan = yan;
    }

    public Hong getHong() {
        return hong;
    }

    public void setHong(Hong hong) {
        this.hong = hong;
    }

}

测试类

这里测试一下浅克隆的效果:

浅克隆一个虹猫,外表特征一样,但是只有一个灵魂。

克隆虹猫身体受到伤害,本体虹猫不受影响。

克隆虹猫精神受到伤害,本体虹猫也受到同样的伤害。

public class Demo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Qian qian = new Qian("两只手", "两只脚", "两只眼", new Hong("完整的灵魂"));
        Qian qian1 = qian.clone();
        System.out.printf("虹猫少侠本体的身体状态:%s,%s,%s,%s,", qian.getHong().getLh(), qian.getJiao(), qian.getShou(), qian.getYan());
        System.out.println();
        System.out.printf("虹猫少侠一号的身体状态:%s,%s,%s,%s,", qian1.getHong().getLh(), qian1.getJiao(), qian1.getShou(), qian1.getYan());

    }
}

克隆出来了一个虹猫一号,所有属性都一模一样

public class Demo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Qian qian = new Qian("两只手", "两只脚", "两只眼", new Hong("完整的灵魂"));
        Qian qian1 = qian.clone();
        qian1.getHong().setLh("灵魂受到攻击");
        qian1.setJiao("断了一只脚");
        System.out.printf("虹猫少侠本体的身体状态:%s,%s,%s,%s,", qian.getHong().getLh(), qian.getJiao(), qian.getShou(), qian.getYan());
        System.out.println();
        System.out.printf("虹猫少侠一号的身体状态:%s,%s,%s,%s,", qian1.getHong().getLh(), qian1.getJiao(), qian1.getShou(), qian1.getYan());
    }
}

这里克隆虹猫的脚和灵魂都受到了伤害,本体虹猫的身体没有受到影响,但是灵魂却受到了伤害。

总结

一、为什么浅克隆中虹猫一号的脚受到了伤害,本体虹猫却没受到伤害?

二、为什么浅克隆中虹猫一号的灵魂受到了伤害,本体虹猫也受到了伤害?

因为创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。 两个虹猫的灵魂指向同一个内存地址,所以存储的是同一个灵魂。

深克隆

案例:克隆虹猫

深克隆一个虹猫,外表特征一样,都有独立灵魂。

克隆虹猫身体受到伤害,本体虹猫不受影响。

克隆虹猫精神受到伤害,本体虹猫也不受影响。

代码实现

虹猫灵魂状态类

这里声明了虹猫的灵魂状态,并且实现了Cloneable 接口,克隆一个虹猫灵魂

public class Hong implements Cloneable {
    //虹猫的灵魂状态
    private String lh;

    Hong(String lh) {
        this.lh = lh;
    }

    Hong() {
    }

    public Hong clone() throws CloneNotSupportedException {
        return (Hong) super.clone();
    }

    public String getLh() {
        return lh;
    }

    public void setLh(String lh) {
        this.lh = lh;
    }

}

虹猫个体类

重写了clone方法,在clone方法中调用了hong.clone()方法克隆了一个虹猫灵魂

public class Qian implements Cloneable {
    private String shou;
    private String jiao;
    private String yan;
    private Hong hong;

    Qian() {
    }

    Qian(String shou, String jiao, String yan, Hong hong) {
        this.hong = hong;
        this.shou = shou;
        this.jiao = jiao;
        this.yan = yan;
    }

    public Qian clone() throws CloneNotSupportedException {
        Qian qian = (Qian) super.clone();
        hong = hong.clone();
        return qian;

    }

    public String getShou() {
        return shou;
    }

    public void setShou(String shou) {
        this.shou = shou;
    }

    public String getJiao() {
        return jiao;
    }

    public void setJiao(String jiao) {
        this.jiao = jiao;
    }

    public String getYan() {
        return yan;
    }

    public void setYan(String yan) {
        this.yan = yan;
    }

    public Hong getHong() {
        return hong;
    }

    public void setHong(Hong hong) {
        this.hong = hong;
    }

}

测试类

这里测试一下浅克隆的效果:

深克隆一个虹猫,外表特征一样,都有独立灵魂。

克隆虹猫身体受到伤害,本体虹猫不受影响。

克隆虹猫精神受到伤害,本体虹猫也不受影响。

public class Demo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Qian qian = new Qian("两只手", "两只脚", "两只眼", new Hong("完整的灵魂"));
        Qian qian1 = qian.clone();
        qian1.getHong().setLh("灵魂受到攻击");
        qian1.setJiao("断了一只脚");
        System.out.printf("虹猫少侠本体的身体状态:%s,%s,%s,%s,", qian.getHong().getLh(), qian.getJiao(), qian.getShou(), qian.getYan());
        System.out.println();
        System.out.printf("虹猫少侠一号的身体状态:%s,%s,%s,%s,", qian1.getHong().getLh(), qian1.getJiao(), qian1.getShou(), qian1.getYan());
    }
}

深克隆出的虹猫完全是个独立的个体,再也不用受限制了。

总结

深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

到此这篇关于Java 设计模式以虹猫蓝兔的故事讲解原型模式的文章就介绍到这了,更多相关Java 原型模式内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java设计模式之原型模式的示例详解

    目录 定义 案例 需求 方案一 方案二 对比分析 总结 定义 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象 即实现了一个原型接口,该接口用于创建当前对象的克隆,当直接创建对象的代价比较大时,则采用这种模式 案例 需求 张三要打印100000份照片 方案一 定义照片类 /** * 照片类 * @author:liyajie * @createTime:2022/2/15 11:47 * @version:1.0 */ @Data @AllArgsConstructor publi

  • 深入理解Java设计模式之原型模式

    目录 一.前言 二.什么是原型模式 三.原型模式的适用场景 四.原型模式的实现 1.浅拷贝实现 2.深拷贝实现 五.总结 一.前言 单例模式可以避免重复创建消耗资源的对象,但是却不得不共用对象.若是对象本身也不让随意访问修改时,怎么办?通常做法是备份到副本,其它对象操作副本,最后获取权限合并,类似git上的PR操作. 二.什么是原型模式 原型模式用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象.需要注意的关键字是,新的对象,类没变..NET在System命名空间中提供了Cloneab

  • java设计模式--原型模式详解

    目录 引例 原型模式 浅拷贝 在原先Sheep类基础上实现Cloneable接口,重写clone方法. 客户端调用 Sheep类 新添的Cow类 客户端调用克隆 深拷贝 1.Cow类也实现Cloneable接口 Sheep类的clone再添加调用cow的clone 客户端调用 1.Cow类实现序列化接口,不必实现Cloneable接口了 2.在Sheep类实现序列化接口 3.客户端调用 总结 引例 问题: 现在有一只羊(包含属性:名字Dolly.年龄2),需要克隆10只属性完全相同的羊. 一般解

  • JAVA设计模式---原型模式你了解吗

    目录 介绍 角色 Java语言提供的clone()方法 代码演示-克隆羊 结论 深浅拷贝 深浅拷贝探讨 实现深克隆的方式一 : 手动对引用对象进行克隆 实现深克隆的方式二 :序列化 原型模式对单例模式的破坏 优缺点 原型模式在Spring中的应用场景 总结 介绍 原型模式(Prototype Pattern):使用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.原型模式是一种对象创建型模式. 原型模式的工作原理很简单:将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过

  • Java 超详细讲解设计模式之原型模式讲解

    目录 传统方式 原型模式基本介绍 原型模式在spring框架中源码分析 深入讨论-浅讨论和深拷贝 原型模式的注意事项和细节 传统方式 克隆羊问题 现在有一只羊 tom,姓名为: tom,年龄为:1,颜色为:白色,请编写程序创建和 tom羊属性完全相同的10只羊. 传统方式解决克隆羊问题 思路分析(图解) 代码演示: public class Sheep { private String name; private int age; private String color; public She

  • Java 深入探讨设计模式之原型模式篇

    目录 传统方式 原型模式基本介绍 原型模式在spring框架中源码分析 深入讨论-浅讨论和深拷贝 原型模式的注意事项和细节 传统方式 克隆羊问题 现在有一只羊 tom,姓名为: tom,年龄为:1,颜色为:白色,请编写程序创建和 tom羊属性完全相同的10只羊. 传统方式解决克隆羊问题 思路分析(图解) 代码演示: public class Sheep { private String name; private int age; private String color; public She

  • Java设计模式之java原型模式详解

    目录 介绍 角色 Java语言提供的clone()方法 代码演示-克隆羊 结论 深浅拷贝 深浅拷贝探讨 实现深克隆的方式一 : 手动对引用对象进行克隆 实现深克隆的方式一 :序列化 原型模式对单例模式的破坏 优缺点 适用场景 原型模式在Spring中的应用场景 总结 介绍 原型模式(Prototype Pattern):使用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.原型模式是一种对象创建型模式. 原型模式的工作原理很简单:将一个原型对象传给那个要发动创建的对象,这个要发动创建

  • Java 深入理解创建型设计模式之原型模式

    1.思考问题 现在有一只羊 tom,姓名为: tom,年龄为:1,颜色为:白色,请编写程序创建和 tom羊属性完全相同的10只羊. 按照传统的思路来,我们可能会按照下面的方式去写. 那么这种写法的优缺点自然而然就出来了: 优点是比较好理解,简单易操作. 缺点是在创建新的对象时,总是需要重新获取原始对象的属性,如果创建的对象比较复杂时,效率较低.总是需要重新初始化对象,而不是动态地获得对象运行时的状态,不够灵活. 改进的思路分析:Java中Object类是所有类的根类,Object类提供了一个 c

  • Java 设计模式以虹猫蓝兔的故事讲解原型模式

    目录 什么是原型模式 优点 缺点 应用场景 浅克隆 代码实现 总结 深克隆 代码实现 总结 什么是原型模式 原型(Prototype)模式的定义如下: 用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象.在这里,原型实例指定了要创建的对象的种类.用这种方式创建对象非常高效,根本无须知道对象创建的细节.例如,Windows 操作系统的安装通常较耗时,如果复制就快了很多.在生活中复制的例子非常多,这里不一一列举了. 优点 1.Java 自带的原型模式基于内存二进制流的

  • Java 设计模式以虹猫蓝兔的故事讲解建造者模式

    目录 什么是建造者模式 优点 缺点 知识点 建造者模式实现 丹药 抽象丹方 九转仙丹丹方 太虚化神丹丹方 神医豆豆 测试 总结 什么是建造者模式 建造者(Builder)模式的定义: 指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式.它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成.它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的. 优点 1.封装性好,构建和表示分离. 2.扩展性好,各个具体的建造者相

  • Java设计模式以虹猫蓝兔的故事讲解代理模式

    目录 什么是代理模式 优点 缺点 知识点 代理模式实现 卖酒 干娘的酒馆 大奔的酒摊 测试 总结 模式: 代理模式 案例: 大奔代干娘卖酒 什么是代理模式 代理模式的定义: 由于某些原因需要给某对象提供一个代理以控制对该对象的访问.这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介. 优点 1.代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用: 2.代理对象可以扩展目标对象的功能: 3.代理模式能将客户端与目标对象分离,在一定程度上降低了系统

  • Java设计模式以虹猫蓝兔的故事讲解桥接模式

    目录 什么是桥接模式 优点 缺点 知识点 桥接模式实现 颜色 黄色 红色 裙子 长裙 短裙 测试 总结 模式: 桥接模式 案例: 蓝兔宫主买裙子 什么是桥接模式 桥接(Bridge)模式的定义如下: 将抽象与实现分离,使它们可以独立变化.它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度. 优点 1.抽象与实现分离,扩展能力强 2.符合开闭原则 3.符合合成复用原则 4.其实现细节对客户透明 缺点 由于聚合关系建立在抽象层,要求开发者针对抽象化进行设计与编程,能正确地识

  • Java 设计模式以虹猫蓝兔的故事讲解单例模式

    目录 专栏介绍 本期介绍 什么是单例模式 懒汉式一 正常模式 单例模式 为什么线程不安全呢 懒汉式二 为什么线程安全呢 饿汉式 懒汉式与饿汉式的区别 专栏介绍 [JAVA长虹键法] 主要讲了23种设计模式,本系列专栏会以虹猫蓝兔七侠传的故事为例来给大家详细分析所有模式,希望能给大家带来帮助! 本期介绍 模式: 单例模式 案例: 虹猫蓝兔造剑 什么是单例模式 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的

  • Java 设计模式以虹猫蓝兔的故事讲解简单工厂模式

    目录 专栏介绍 本期介绍 什么是简单工厂模式 优点 缺点 应用场景 简单工厂的实现 专栏介绍 本系列专栏会以虹猫蓝兔七侠传的故事为例来给大家详细分析所有模式,希望能给大家带来帮助! 本期介绍 模式: 简单工厂模式 案例: 一个天外陨石(抽象产品),三把剑(产品), 一个铸剑师(工厂). 虹猫蓝兔莎莉分别找铸剑师造了三把剑. 什么是简单工厂模式 工厂模式的定义: 定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中.这满足创建型模式中所要求的"创建与使用相分离"

  • Java 设计模式以虹猫蓝兔的故事讲解单例模式

    目录 专栏介绍 本期介绍 什么是单例模式 懒汉式一 正常模式 单例模式 为什么线程不安全呢 懒汉式二 为什么线程安全呢 饿汉式 懒汉式与饿汉式的区别 专栏介绍 [JAVA长虹键法] 主要讲了23种设计模式,本系列专栏会以虹猫蓝兔七侠传的故事为例来给大家详细分析所有模式,希望能给大家带来帮助! 本期介绍 模式: 单例模式 案例: 虹猫蓝兔造剑 什么是单例模式 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的

  • Java设计模式以虹猫蓝兔的故事讲解适配器模式

    目录 什么是适配器模式 优点 缺点 知识点 适配器模式实现 类适配器 长虹剑气 火舞旋风剑气 火晶石 测试 对象适配器 长虹剑气 火舞旋风剑气 火晶石 测试 总结 模式: 适配器模式 案例: 虹猫利用火晶石催发火舞旋风剑气 什么是适配器模式 适配器模式(Adapter)的定义如下: 将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作.适配器模式分为类结构型模式和对象结构型模式两种,前者类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的

  • Java设计模式以虹猫蓝兔的故事讲解装饰器模式

    目录 什么是装饰器模式 优点 缺点 知识点 装饰器模式实现 七侠 虹猫 加料 加盐 加孜然 测试 总结 模式: 装饰器模式 案例: 黑小虎抓住了七侠,把虹猫烤了 什么是装饰器模式 装饰器(Decorator)模式的定义: 指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式. 优点 1.装饰器是继承的有力补充,比继承灵活,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用 2.通过使用不用装饰类及这些装饰类的排列组合,可以实现不同效

  • Java设计模式之备忘录模式_动力节点Java学院

    定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样就可以将该对象恢复到原先保存的状态 类型:行为类 类图: 我们在编程的时候,经常需要保存对象的中间状态,当需要的时候,可以恢复到这个状态.比如,我们使用Eclipse进行编程时,假如编写失误(例如不小心误删除了几行代码),我们希望返回删除前的状态,便可以使用Ctrl+Z来进行返回.这时我们便可以使用备忘录模式来实现. 备忘录模式的结构 发起人:记录当前时刻的内部状态,负责定义哪些属于备份范围的状态,负责创建和

随机推荐