前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【Java设计模式】006-原型模式

【Java设计模式】006-原型模式

作者头像
訾博ZiBo
发布2025-01-06 14:00:12
发布2025-01-06 14:00:12
6100
代码可运行
举报
运行总次数:0
代码可运行

二、原型模式

第二次梳理:原型模式的目的是在创建多个同一个类的相同或相似对象(属性等完全相同,或者稍有不同)时提高效率,直接对原有对象进行复制,若有个别属性的不同再对个别属性进行修改即可!浅克隆(浅拷贝)就是克隆的时候只克隆基本数据类型的属性,对象克隆的是内存地址,深克隆(深拷贝)克隆所有数据!原型管理器是对多个被克隆对象的集中管理,以方便克隆!时间:2021年05月13日 09点23分40秒

1、概述

用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。

2、应用场景

  • 对象之间相同或相似,即只是个别的几个属性不同的时候;
  • 创建对象成本较大,例如初始化时间长,占用CPU太多,或者占用网络资源太多等,需要优化资源;
  • 创建一个对象需要繁琐的数据准备或访问权限等,需要提高性能或者提高安全性;
  • 系统中大量使用该类对象,且各个调用者都需要给它的属性重新赋值;

3、优缺点

优点
  • Java自带的原型模式基于内存二进制流的复制,在性能上比直接 new 一个对象更加优良;
  • 可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份,并将其状态保存起来,简化了创建对象的过程,以便在需要的时候使用(例如恢复到历史某一状态),可辅助实现撤销操作;
缺点
  • 需要为每一个类都配置一个 clone 方法;
  • clone 方法位于类的内部,当对已有类进行改造的时候,需要修改代码,违背了开闭原则;
  • 当实现深克隆时,需要编写较为复杂的代码,而且当对象之间存在多重嵌套引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现起来会比较麻烦。因此,深克隆、浅克隆需要运用得当。

4、主要角色

  • 抽象原型类:规定了具体原型对象必须实现的接口;
  • 具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象;
  • 访问类:使用具体原型类中的 clone() 方法来复制新的对象;

5、深克隆与浅克隆

也就是深拷贝与浅拷贝

深克隆

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

浅克隆

创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址;

6、通过Cloneable接口实现浅克隆

实体类
代码语言:javascript
代码运行次数:0
运行
复制
package com.zibo.design.one;

public class Dog implements Cloneable {
    private final String name;
    private final int age;

    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("原型创建成功!");
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        System.out.println("圆形复制成功!");
        return super.clone();
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
测试类
代码语言:javascript
代码运行次数:0
运行
复制
package com.zibo.design.one;

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Dog dog = new Dog("小黑", 1);
        Dog dog1 = (Dog)dog.clone();
        Dog dog2 = (Dog)dog.clone();
        Dog dog3 = (Dog)dog.clone();
        System.out.println(dog);
        System.out.println(dog1);
        System.out.println(dog2);
        System.out.println(dog3);
    }
}
运行结果
代码语言:javascript
代码运行次数:0
运行
复制
原型创建成功!
圆形复制成功!
圆形复制成功!
圆形复制成功!
Dog{name='小黑', age=1}
Dog{name='小黑', age=1}
Dog{name='小黑', age=1}
Dog{name='小黑', age=1}

7、改良5

上面的例子是完全的克隆,一点属性都没有,实际生活中总要有所区分吧

实体类
代码语言:javascript
代码运行次数:0
运行
复制
package com.zibo.design.one;

public class Dog implements Cloneable {
    private String name;
    private final int age;

    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("原型创建成功!");
    }

    // 我们可以自定义克隆,传入名字,克隆之后改一个名字
    protected Dog clone(String name) throws CloneNotSupportedException {
        System.out.println("原型复制成功!");
        Dog clone = (Dog)super.clone();
        clone.name = name;
        return clone;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
测试类
代码语言:javascript
代码运行次数:0
运行
复制
package com.zibo.design.one;

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Dog dog = new Dog("大狗子", 1);
        Dog dog1 = dog.clone("二狗子");
        Dog dog2 = dog.clone("三狗子");
        Dog dog3 = dog.clone("四狗子");
        System.out.println(dog);
        System.out.println(dog1);
        System.out.println(dog2);
        System.out.println(dog3);
    }
}
运行结果
代码语言:javascript
代码运行次数:0
运行
复制
原型创建成功!
原型复制成功!
原型复制成功!
原型复制成功!
Dog{name='大狗子', age=1}
Dog{name='二狗子', age=1}
Dog{name='三狗子', age=1}
Dog{name='四狗子', age=1}

8、原型管理器

原型模式的扩展

概述

原型管理器(Prototype Manager)是将多个原型对象存储在一个集合中供客户端使用,它是一个专门负责克隆对象的工厂,其中定义了一个集合用于存储原型对象,如果需要某个原型对象的一个克隆,可以通过复制集合中对应的原型对象来获得。在原型管理器中针对抽象原型类进行编程,以便扩展;

功能类
代码语言:javascript
代码运行次数:0
运行
复制
package com.zibo.design.one;

import java.util.HashMap;
import java.util.Map;

public interface Dog extends Cloneable{
    Dog clone() throws CloneNotSupportedException;
}

// 原型管理器
class PrototypeManager {
    // 存放原型
    private final Map<String,Dog> map = new HashMap<>();
    // 饿汉式实例化管理器
    private static final PrototypeManager manager  = new PrototypeManager();

    // 装载所有原型
    private PrototypeManager() {
        map.put("bigDog",new BigDog("大狗子",10));
        map.put("littleDog",new LittleDog("小狗子",1));
    }

    public static PrototypeManager getManager(){
        return manager;
    }

    // 克隆原型
    public Dog getDog(String key) throws CloneNotSupportedException {
        return map.get(key).clone();
    }
}

// 大狗原型
class BigDog implements Dog {
    private final String name;
    private final int age;

    public BigDog(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("大狗原型创建成功!");
    }

    @Override
    public Dog clone() throws CloneNotSupportedException {
        System.out.println("大狗原型复制成功!");
        return (Dog) super.clone();
    }

    @Override
    public String toString() {
        return "bigDog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

// 小狗原型
class LittleDog implements Dog {

    private final String name;
    private final int age;

    public LittleDog(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("小狗原型创建成功!");
    }

    @Override
    public Dog clone() throws CloneNotSupportedException {
        System.out.println("小狗原型复制成功!");
        return (Dog) super.clone();
    }

    @Override
    public String toString() {
        return "littleDog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
测试类
代码语言:javascript
代码运行次数:0
运行
复制
package com.zibo.design.one;

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        PrototypeManager manager = PrototypeManager.getManager();
        Dog bigDog = manager.getDog("bigDog");
        System.out.println(bigDog);
        Dog littleDog = manager.getDog("littleDog");
        System.out.println(littleDog);
    }
}
运行结果
代码语言:javascript
代码运行次数:0
运行
复制
大狗原型创建成功!
小狗原型创建成功!
大狗原型复制成功!
bigDog{name='大狗子', age=10}
小狗原型复制成功!
littleDog{name='小狗子', age=1}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-01-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 二、原型模式
    • 1、概述
    • 2、应用场景
    • 3、优缺点
      • 优点
      • 缺点
    • 4、主要角色
    • 5、深克隆与浅克隆
      • 深克隆
      • 浅克隆
    • 6、通过Cloneable接口实现浅克隆
      • 实体类
      • 测试类
      • 运行结果
    • 7、改良5
      • 实体类
      • 测试类
      • 运行结果
    • 8、原型管理器
      • 概述
      • 功能类
      • 测试类
      • 运行结果
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档