原型(克隆)模式
创始人
2024-03-01 20:19:25
0

文章目录

    • 思考原型(克隆)模式
      • 1.原型模式的本质
      • 2.何时选用原型模式
      • 3.优缺点
      • 4.实现
        • 原型模式(浅克隆)
        • 原型模式(深克隆)
        • java浅克隆
        • java深克隆

思考原型(克隆)模式

原型模式顾名思义通过一个接口实现快速创建对象

1.原型模式的本质

原型模式的本质:克隆生成对象。

克隆是手段,目的是生成新的对象实例。正是因为原型的目的是为了生成新的对象实例,原型模式通常是被归类为创建型的模式。

原型模式也可以用来解决“只知接口而不知实现的问题”,使用原型模式,可以出现一种独特的“接口造接口”的景象,这在面向接口编程中很有用。同样的功能也可以考虑使用工厂来实现。

另外,原型模式的重心还是在创建新的对象实例,至于创建出来的对象,其属性的值是否一定要和原型对象属性的值完全一样,这个并没有强制规定,只不过在目前大多数实现中,克隆出来的对象和原型对象的属性值是一样的。

也就是说,可以通过克隆来创造值不一样的实例,但是对象类型必须一样。可以有部分甚至是全部的属性的值不一样,可以有选择性地克隆,就当是标准原型模式的一个变形使用吧。

2.何时选用原型模式

建议在以下情况时选用原型模式。

  • 如果一个系统想要独立于它想要使用的对象时,可以使用原型模式,让系统只面向接口编程,在系统需要新的对象的时候,可以通过克隆原型来得到。
  • 如果需要实例化的类是在运行时刻动态指定时,可以使用原型模式,通过克隆原型来得到需要的实例。

3.优缺点

原型模式的优点

  • 对客户端隐藏具体的实现类型
    原型模式的客户端只知道原型接口的类型,并不知道具体的实现类型,从而减少了客户端对这些具体实现类型的依赖。

  • 在运行时动态改变具体的实现类型
    原型模式可以在运行期间,由客户来注册符合原型接口的实现类型,也可以动态地改变具体的实现类型,看起来接口没有任何变化,但其实运行的已经是另外一个类实例了。因为克隆一个原型就类似于实例化一个类。

原型模式的缺点

  • 原型模式最大的缺点就在于每个原型的子类都必须实现 clone 的操作,尤其在包含引用类型的对象时,clone方法会比较麻烦,必须要能够递归地让所有的相关对象都要正确地实现克隆。

4.实现

原型模式(浅克隆)

克隆接口

/*** @description:需要克隆方法实现此接口*/
public interface OrderApi {/*** 克隆方法* @return*/OrderApi clone();
}

实现类

/*** @description:个人订单*/
@Data
@ToString
public class PersonOrder implements OrderApi{/*** 用户名*/private String personName;/*** 产品id*/private Integer productId;private CompanyOrder companyOrder;/*** 克隆对象* @return*/@Overridepublic OrderApi clone() {PersonOrder personOrder = new PersonOrder();personOrder.setPersonName(this.personName);personOrder.setProductId(this.productId);//引用对象克隆personOrder.setCompanyOrder(this.companyOrder);return personOrder;}
}/*** @description:公司订单*/
@Data
@ToString
public class CompanyOrder implements OrderApi{/*** 公司名*/private String companyName;/*** 产品id*/private Integer productId;/*** 克隆对象* @return*/@Overridepublic OrderApi clone() {CompanyOrder companyOrder = new CompanyOrder();companyOrder.setCompanyName(this.companyName);companyOrder.setProductId(this.productId);return companyOrder;}
}

测试类

/*** @description:测试类*/
public class Client {public static void main(String[] args) {PersonOrder personOrder = new PersonOrder();personOrder.setPersonName("张三");personOrder.setProductId(10001);CompanyOrder companyOrder = new CompanyOrder();companyOrder.setCompanyName("字节跳动");companyOrder.setProductId(10002);personOrder.setCompanyOrder(companyOrder);System.out.println("原对象:"+personOrder);//自己实现克隆OrderApi personClone = personOrder.clone();System.out.println("克隆对象:"+personClone);//修改原对象中引用对象的值companyOrder.setCompanyName("88888888888");System.out.println("克隆对象:"+personClone);}
}

结果
在这里插入图片描述

原型模式(深克隆)

实现深度克隆只需克隆引用对象时,调用它自己的克隆方法,一直传递下去

/*** 克隆对象* @return*/
@Override
public OrderApi clone() {PersonOrder personOrder = new PersonOrder();personOrder.setPersonName(this.personName);personOrder.setProductId(this.productId);personOrder.setCompanyOrder((CompanyOrder) this.companyOrder.clone());return personOrder;
}

结果
在这里插入图片描述

java提供的克隆

1、浅克隆:对当前对象进行克隆,并克隆该对象所包含的8种基本数据类型和String类型属性(拷贝一份该对象并重新分配内存,即产生了新的对象);但如果被克隆的对象中包含除8中数据类型和String类型外的其他类型的属性,浅克隆并不会克隆这些属性(即不会为这些属性分配内存,而是引用原来对象中的属性)
2、深克隆:深拷贝会完全复制整个对象,包括这个对象所包含的内部对象。

java浅克隆

1.实现Cloneable接口
2.重写clone方法

/*** @description:个人订单*/
@Data
@ToString
public class PersonOrder2 implements Cloneable{/*** 用户名*/private String personName;/*** 产品id*/private Integer productId;private CompanyOrder2 companyOrder2;@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}@Data
@ToString
public class CompanyOrder2 implements Cloneable{/*** 公司名*/private String companyName;/*** 产品id*/private Integer productId;@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}

测试

/*** @description:测试类*/
public class Client {public static void main(String[] args) throws CloneNotSupportedException {CompanyOrder2 companyOrder2 = new CompanyOrder2();companyOrder2.setCompanyName("字节跳动");companyOrder2.setProductId(10002);PersonOrder2 personOrder2 = new PersonOrder2();personOrder2.setPersonName("张三");personOrder2.setProductId(10001);personOrder2.setCompanyOrder2(companyOrder2);System.out.println("原对象:"+personOrder2);//java浅克隆Object clone = personOrder2.clone();System.out.println("克隆对象:"+clone);companyOrder2.setCompanyName("9999999999");System.out.println("克隆对象:"+clone);}
}

结果
在这里插入图片描述

可以看到,虽然克隆出来了一个一模一样的对象,但是修改原对象的属性,克隆的对象属性也改变了,这就是浅克隆,原对象和克隆对象的引用属性共同指向一个内存地址

java深克隆

实现深度克隆只需克隆引用对象时,调用它自己的克隆方法,一直传递下去,原理和上面的原型实现深克隆一样

@Override
protected Object clone() throws CloneNotSupportedException {PersonOrder2 clone = (PersonOrder2) super.clone();clone.setCompanyOrder2((CompanyOrder2) this.companyOrder2.clone());return clone;
}

结果
在这里插入图片描述

相关内容

热门资讯

(图表)十年来全国检察机关共办... 新华社图表,北京,2025年12月22日 记者从最高人民法院、最高人民检察院12月22日举行的发布...
反思独居蒋女士离世事件:补齐制... 家住上海虹口区的46岁独居人士蒋女士,12月14日因病离世,但她的遗产不能用来购买墓地,引发舆论广泛...
俄副外长:保证不进攻欧盟北约,... 【文/观察者网 柳白】 据俄新社报道,当地时间12月22日,俄罗斯外交部副部长谢尔盖·里亚布科夫在...
贵州一策律师事务所:让法治精神... 今年10月,贵州一策律师事务所荣获2025年度贵州省绿色网络工作室荣誉称号,成为全省20家获此殊荣的...
日本多名教职人员因性暴力或性犯... 新华社东京12月22日电(记者陈泽安 李子越)据日本文部科学省22日公布的数据,日本2024财年(2...
贵州仁山律师事务所:以法为炬传... 今年10月,贵州仁山律师事务所凭借深耕婚姻法律网络科普的扎实成效、线上线下融合的普法创新实践,斩获贵...
法治青年说|涉及网约车、公用电... 12月22日,全国人大常委会法工委关于2025年备案审查工作情况的报告提请全国人大常委会会议审议。在...
原创 再... 电视人朴娜莱向前任经纪人追加提起刑事诉讼,使得原本就紧绷的法律纠纷进一步升级。 据韩国媒体报道称:...
因涉嫌犯罪,交建股份实控人俞发... 12月22日晚间,交建股份(603815.SH)公告,公司收到公司实际控制人俞发祥家属通知,俞发祥因...
新疆火炬(603080)披露公... 截至2025年12月22日收盘,新疆火炬(603080)报收于22.81元,较前一交易日上涨0.35...