0
点赞
收藏
分享

微信扫一扫

原型模式必知必会


文章目录

  • ​​类图​​
  • ​​实例​​
  • ​​深克隆​​
  • ​​深克隆破坏单例解决方式​​
  • ​​个人理解​​
  • ​​原型克隆和new的区别​​
  • ​​原型模式和抽象工厂模式的区别​​
  • ​​本质​​
  • ​​代码地址:​​

类图

原型模式必知必会_深克隆


原型模式必知必会_ide_02

实例

public interface Prototype{
Prototype clone();
}

public class ConcretePrototypeA implements Prototype {

private int age;
private String name;
private List hobbies;

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public List getHobbies() {
return hobbies;
}

public void setHobbies(List hobbies) {
this.hobbies = hobbies;
}

@Override
public ConcretePrototypeA clone() {
ConcretePrototypeA concretePrototype = new ConcretePrototypeA();
concretePrototype.setAge(this.age);
concretePrototype.setName(this.name);
concretePrototype.setHobbies(this.hobbies);
return concretePrototype;
}

}

public class ConcretePrototypeB implements Prototype {

@Override
public Prototype clone() {
return null;
}
}

public class Client {

private Prototype prototype;

public Client(Prototype prototype){
this.prototype = prototype;
}
public Prototype startClone(Prototype concretePrototype){
return (Prototype)concretePrototype.clone();
}

}

public class PrototypeTest {

public static void main(String[] args) {

// 创建一个具体的需要克隆的对象
ConcretePrototypeA concretePrototype = new ConcretePrototypeA();
// 填充属性,方便测试
concretePrototype.setAge(18);
concretePrototype.setName("prototype");
List hobbies = new ArrayList<String>();
concretePrototype.setHobbies(hobbies);
System.out.println(concretePrototype);

// 创建Client对象,准备开始克隆
Client client = new Client(concretePrototype);
ConcretePrototypeA concretePrototypeClone = (ConcretePrototypeA) client.startClone(concretePrototype);
System.out.println(concretePrototypeClone);

System.out.println("克隆对象中的引用类型地址值:" + concretePrototypeClone.getHobbies());
System.out.println("原对象中的引用类型地址值:" + concretePrototype.getHobbies());
System.out.println("对象地址比较:"+(concretePrototypeClone.getHobbies() == concretePrototype.getHobbies()));


}
}

原型模式必知必会_设计模式_03

深克隆

例子:

原型模式必知必会_浅克隆_04

public class Monkey {
public int height;
public int weight;
public Date birthday;
}

public class JinGuBang implements Serializable {
public float h = 100;
public float d = 10;

public void big(){
this.d *= 2;
this.h *= 2;
}

public void small(){
this.d /= 2;
this.h /= 2;
}
}

public class QiTianDaSheng extends Monkey implements Cloneable,Serializable {

public JinGuBang jinGuBang;

public QiTianDaSheng(){
//只是初始化
this.birthday = new Date();
this.jinGuBang = new JinGuBang();
}

@Override
protected Object clone() throws CloneNotSupportedException {
return this.deepClone();
}


//深克隆
public Object deepClone(){
try{

ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);

ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);

QiTianDaSheng copy = (QiTianDaSheng)ois.readObject();
copy.birthday = new Date();
return copy;

}catch (Exception e){
e.printStackTrace();
return null;
}

}


public QiTianDaSheng shallowClone(QiTianDaSheng target){

QiTianDaSheng qiTianDaSheng = new QiTianDaSheng();
qiTianDaSheng.height = target.height;
qiTianDaSheng.weight = target.height;

qiTianDaSheng.jinGuBang = target.jinGuBang;
qiTianDaSheng.birthday = new Date();
return qiTianDaSheng;
}

//浅克隆
public QiTianDaSheng deep2(QiTianDaSheng target){

QiTianDaSheng qiTianDaSheng = new QiTianDaSheng();
qiTianDaSheng.height = target.height;
qiTianDaSheng.weight = target.height;

qiTianDaSheng.jinGuBang = target.jinGuBang;
qiTianDaSheng.birthday = new Date();
return qiTianDaSheng;
}

}

public class DeepCloneTest {

public static void main(String[] args) {

QiTianDaSheng qiTianDaSheng = new QiTianDaSheng();
try {
QiTianDaSheng clone = (QiTianDaSheng)qiTianDaSheng.clone();
System.out.println("深克隆:" + (qiTianDaSheng.jinGuBang == clone.jinGuBang));
} catch (Exception e) {
e.printStackTrace();
}

QiTianDaSheng q = new QiTianDaSheng();
QiTianDaSheng n = q.shallowClone(q);
System.out.println("浅克隆:" + (q.jinGuBang == n.jinGuBang));


}
}

原型模式必知必会_设计模式_05

深克隆破坏单例解决方式

要么你我们的单例类不实现Cloneable接口;
要么我们重写clone()方法,在clone方法中返回单例对象即可,具体代码如下:

@Override
protected Object clone() throws CloneNotSupportedException{
return INSTANCE;
}

Cloneable源码分析先看我们常用的ArrayList就实现了Cloneable接口,来看代码clone()方法的实现:`

public Object clone(){
try{
ArrayList<?>v=(ArrayList<?>)
super.clone();v.elementData=Arrays.copyOf(elementData,size);
v.modCount=0;
return v;
}catch(CloneNotSupportedExceptione){
。。。
}

个人理解

感觉和之前new出来一个对象,再set值一样,只是,这个set的功能在对象内部。对外只暴露一个clone或者其他自定义接口。

原型克隆和new的区别

原型模式必知必会_设计模式_06

原型模式和抽象工厂模式的区别

原型模式必知必会_浅克隆_07

本质

本质: 克隆生成对象。

代码地址:

​​https://github.com/hufanglei/pattern-learn/tree/master/src/main/java/com/example/prototype​​​

个人微信公众号:

搜索: 怒放de每一天

不定时推送相关文章,期待和大家一起成长!!

原型模式必知必会_浅克隆_08


举报

相关推荐

0 条评论