前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >原型模式

原型模式

作者头像
许喜朝
发布2022-05-05 16:58:22
2000
发布2022-05-05 16:58:22
举报

原型模式

模式定义

指原型实例指定创建对象的种类,并且通过拷贝这些原型创建一个新的对象

换句话讲就是我们通常所说的复制粘贴,这就是原型模式的思想

实现

被克隆的对象实现Cloneable接口

重写clone方法调用父类的clone方法

代码语言:javascript
复制
public class PrototypeTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        Product4 product4 = new Product4("part1", "part2", "part3", 1, 2,baseInfo);
        Product4 clone = product4.clone();
      //输出两个不同的对象
        System.out.println(product4);
        System.out.println(clone);
    }
}
//被克隆的类
class Product4 implements Cloneable{
    private String part1;
    private String part2;
    private String part3;
    private Integer part4;
    private Integer part5;

    public String getPart1() {
        return part1;
    }

    public void setPart1(String part1) {
        this.part1 = part1;
    }

    public String getPart2() {
        return part2;
    }

    public void setPart2(String part2) {
        this.part2 = part2;
    }

    public String getPart3() {
        return part3;
    }

    public void setPart3(String part3) {
        this.part3 = part3;
    }

    public Integer getPart4() {
        return part4;
    }

    public void setPart4(Integer part4) {
        this.part4 = part4;
    }

    public Integer getPart5() {
        return part5;
    }

    public void setPart5(Integer part5) {
        this.part5 = part5;
    }

    public BaseInfo getBaseInfo() {
        return baseInfo;
    }

    public void setBaseInfo(BaseInfo baseInfo) {
        this.baseInfo = baseInfo;
    }

    public Product4(String part1, String part2, String part3, Integer part4, Integer part5, BaseInfo baseInfo) {
        this.part1 = part1;
        this.part2 = part2;
        this.part3 = part3;
        this.part4 = part4;
        this.part5 = part5;
        this.baseInfo = baseInfo;
    }

    @Override
    public String toString() {
        return "["+super.hashCode()+"]Product4{" +
                "part1='" + part1 + '\'' +
                ", part2='" + part2 + '\'' +
                ", part3='" + part3 + '\'' +
                ", part4=" + part4 +
                ", part5=" + part5 +
                '}';
    }
//重写clone()方法
    @Override
    protected Product4 clone() throws CloneNotSupportedException {
        return ((Product4)super.clone());
    }
}
深拷贝

只拷贝对象中的基本数据类型(8种),对于数组,容器引用对象等不会考贝

浅拷贝

不仅能拷贝基本数据类型,还能拷贝数组,容器,引用对象等

深拷贝问题

在拷贝对象的属性中添加一个引用对象属性。然后修改引用对象属性

引用对象

代码语言:javascript
复制
//被引用对象
class BaseInfo implements Cloneable{
    private String companyName;
    @Override
    public String toString() {
        return "["+super.hashCode()+"]BaseInfo{" +
                "companyName='" + companyName + '\'' +
                '}';
    }

    @Override
    protected BaseInfo clone() throws CloneNotSupportedException {
        return ((BaseInfo) super.clone());
    }

    public String getCompanyName() {
        return companyName;
    }

    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }

    public BaseInfo(String companyName) {
        this.companyName = companyName;
    }
}

在拷贝对象的属性中添加引用对象

代码语言:javascript
复制
private String part1;
private String part2;
private String part3;
private Integer part4;
private Integer part5;
private BaseInfo baseInfo;

查看结果

代码语言:javascript
复制
public static void main(String[] args) throws CloneNotSupportedException {
    BaseInfo baseInfo = new BaseInfo("aaa");
    Product4 product4 = new Product4("part1", "part2", "part3", 1, 2,baseInfo);
    Product4 clone = product4.clone();
    System.out.println(product4);
    System.out.println(clone);
    //修改引用对象
    baseInfo.setCompanyName("bbb");
  //显示修改后的内容
    System.out.println(product4);
    System.out.println(clone);

}

显示修改后的内容,这显然是不可取的

为什么拷贝的对象,引用类型会是同一个呢?

被拷贝对象的引用对象指向一个内存地址a,拷贝对象拷贝后引用类型也指向地址a所以是同一个对象

解决深拷贝问题

那么如何解决呢?

将拷贝对象引用类型的值设置成被拷贝对象引用类型的克隆

引用对象实现Cloneable接口重写clone方法

代码语言:javascript
复制
//被引用对象
class BaseInfo implements Cloneable{
    private String companyName;
    @Override
    public String toString() {
        return "["+super.hashCode()+"]BaseInfo{" +
                "companyName='" + companyName + '\'' +
                '}';
    }
		//重写clone方法
    @Override
    protected BaseInfo clone() throws CloneNotSupportedException {
        return ((BaseInfo) super.clone());
    }

}

被克隆对象重写clone方法

代码语言:javascript
复制
//重写clone方法
    //将拷贝对象引用类型的值设置成被拷贝对象引用类型的克隆
    @Override
    protected Product4 clone() throws CloneNotSupportedException {
        Product4 clone = (Product4) super.clone();
        BaseInfo clone1 = this.baseInfo.clone();
        clone.setBaseInfo(clone1);
        return clone;
    }
使用场景

当我们的类初始化需要消耗很多的资源时,就可以使用原型模式,因为我们的克隆不会执行构造方法,避免了初始化占有的时间和空间

一个对象被其他对象访问,并且能够修改时,访问权限都无效了,什么都能修改

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-12-16,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 原型模式
    • 模式定义
      • 实现
        • 使用场景
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档