场景 如果一个对象,我们希望拷贝一个这个对象,就是弄出来这个类的另外一个实例,实例的属性跟之前的实例是一模一样的
1.常规
package com.example.demo.pattern.prototype;
/**
* @author chenchao
* @date 2021/11/9
*/
public class WithoutPrototypePatternDemo {
public static void main(String[] args) {
// 手头有这么一个对象,需要进行拷贝
Product product = new Product("测试产品", new Component("测试组件"));
// 手动来拷贝
Product copyProduct = new Product(product.getName(), product.getComponent());
System.out.println(copyProduct);
// 问题是什么?
// 代码的拷贝逻辑,是每个要拷贝的调用方自己来实现的
// 相同的拷贝逻辑会分散在很多不同的地方,如果拷贝逻辑改变了,多个调用的地方都要修改代码
// 可维护性、可扩展性,很差
}
public static class Component {
private String name;
public Component(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Component [name=" + name + "]";
}
}
public static class Product {
private String name;
private Component component;
public Product(String name, Component component) {
super();
this.name = name;
this.component = component;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Component getComponent() {
return component;
}
public void setComponent(Component component) {
this.component = component;
}
@Override
public String toString() {
return "Product [name=" + name + ", component=" + component + "]";
}
}
}
2.原型模式
package com.example.demo.pattern.prototype;
/**
* @author chenchao
* @date 2021/11/9
*/
public class PrototypePatternDemo {
public static void main(String[] args) {
try {
Product product = new Product("测试产品", new Component("测试组件"));
Product copyProduct = (Product) product.clone();
System.out.println(copyProduct);
} catch (Exception e) {
e.printStackTrace();
}
// 原型模式,就是在要拷贝的类里实现一个clone()方法,自己拷贝自己
// 拷贝的时候,就两个概念,浅拷贝,深拷贝
// 很多地方要克隆这个对象,不要自己维护克隆的逻辑,即使克隆逻辑修改了,只要在clone()方法里面修改
}
public static class Component {
private String name;
public Component(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Component [name=" + name + "]";
}
@Override
protected Object clone() throws CloneNotSupportedException {
return new Component(getName());
}
}
public static class Product {
private String name;
private Component component;
public Product(String name, Component component) {
super();
this.name = name;
this.component = component;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Component getComponent() {
return component;
}
public void setComponent(Component component) {
this.component = component;
}
@Override
public String toString() {
return "Product [name=" + name + ", component=" + component + "]";
}
@Override
protected Object clone() throws CloneNotSupportedException {
// 浅拷贝,就是我们现在的一个实现
// 就是仅仅简单的对当前所有的变量进行一个拷贝
// return new Product(getName(), getComponent());
// 深考别,递归对自己引用的对象也进行拷贝
return new Product(getName(), (Component)getComponent().clone());
}
}
}
3.说明
原型模式,顾名思义,其实说白了,就是让一个对象可以自己拷贝自己,对象把自己当成一个原型,然后提供一个方法出去,外部要一个对象的克隆和拷贝,直接就copy一份就可以了,但是这里要记住深拷贝和浅拷贝的区别
因为一个对象可能还持有别的对象的引用,浅拷贝就是不管引用的其他对象了;深拷贝就是将引用的对象也一起拷贝一份;一般原型模式都是要支持深拷贝的
而且其实一般实现原型模式的时候,直接是通过覆盖Object类的clone()方法即可,在里面实现自己的拷贝逻辑就可以了
使用原型模式比较好的一点,就是如果别人要拷贝你的对象,不需要调用方自己实现拷贝逻辑,将拷贝逻辑放在对象自己身体里就可以了,对外面调用都是透明的