Javaデザインパターンパターン---プロトタイプパターン



Java Design Pattern Pattern Prototype Pattern



浅いコピー

(1)複製されるクラスは、複製可能なインターフェースを実装します。これは、マークインターフェイスと呼ばれる空のインターフェイスです。これはSerializableインターフェイスに似ており、シリアル化できます。このクラスのオブジェクトをコピーできることを仮想マシンに通知するだけです。

(2)cloneメソッドを書き直します(このメソッドはcloneableインターフェースに属しておらず、Objectクラスに属しています)



Objectクラスによって提供されるメソッドcloneは、オブジェクトの基本型属性をコピーするだけであり(文字列型データもコピーされます)、オブジェクト内の配列と参照オブジェクトはコピーされません。つまり、コピーされたものが所有する参照属性はコピーされません。オブジェクトはすべてプロトタイプオブジェクトの参照属性のアドレスを指します。このコピーは呼び出されます 浅いコピー。

プロトタイプクラスを作成します。



package xidain.lili.prototype import java.util.Date //Prototype public class Sheep implements Cloneable{ int age String name Date birthday public Sheep() {} public Sheep(int age, String name, Date birthday) { super() this.age = age this.name = name this.birthday = birthday } //Rewrite the clone method, modify the permission modifier to public, and return the prototype object @Override public Sheep clone() throws CloneNotSupportedException { return (Sheep) super.clone() // directly call the clone method of the parent Object } 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 Date getBirthday() { return birthday } public void setBirthday(Date birthday) { this.birthday = birthday } }

クローンを作成するには、Cloneableインターフェイスが実装されていない場合、cloneを呼び出すとCloneNotSupportedExceptionがスローされます。

package xidain.lili.prototype import java.util.Date public class Client { public static void main(String[] args) throws CloneNotSupportedException { //Create prototype object Sheep sheep=new Sheep(8,'Dolly',new Date(123142356476L)) System.out.println(sheep) System.out.println(sheep.getAge()) System.out.println(sheep.getName()) System.out.println(sheep.getBirthday()) Sheep clonesheep=sheep.clone() System.out.println(clonesheep) System.out.println(clonesheep.getAge()) System.out.println(clonesheep.getName()) System.out.println(clonesheep.getBirthday()) } }

結果



浅いコピーをテストし、プロトタイプオブジェクトの参照型の属性を変更し、クローン化されたオブジェクトの参照型の属性値も変更されることを確認しますが、文字列型は変更されません。


ディープコピー

これは浅いコピーに対応します。深いコピーはプロトタイプオブジェクトのすべてのプロパティをコピーすることです。実現するには2つの方法があります。


①すべての参照属性のクローンを作成します

package xidain.lili.prototype import java.util.Date //Prototype public class Sheep2 implements Cloneable{ int age String name Date birthday public Sheep2() {} public Sheep2(int age, String name, Date birthday) { super() this.age = age this.name = name this.birthday = birthday } //Rewrite the clone method, modify the permission modifier to public, and return the prototype object @Override public Sheep2 clone() throws CloneNotSupportedException { Sheep2 sheep=(Sheep2) super.clone() sheep.birthday=(Date) this.getBirthday().clone()//clone attribute return sheep// } 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 Date getBirthday() { return birthday } public void setBirthday(Date birthday) { this.birthday = birthday } }


②ディープレプリケーションを実現するためのシリアル化

Serializableインターフェイスを実装するにはプロトタイプクラスが必要です

package xidain.lili.prototype import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream import java.io.IOException import java.io.ObjectInputStream import java.io.ObjectOutputStream import java.util.Date public class Client2 { public static void main(String[] args) throws CloneNotSupportedException, Exception { //Create prototype object Date d=new Date(3473842384l) Sheep sheep=new Sheep(8,'Dolly',d) ByteArrayOutputStream bos=new ByteArrayOutputStream() ObjectOutputStream oos=new ObjectOutputStream(bos) oos.writeObject(sheep) byte[] sheepbyte=bos.toByteArray() ByteArrayInputStream bas=new ByteArrayInputStream(sheepbyte) ObjectInputStream ois=new ObjectInputStream(bas) Sheep clonesheep=(Sheep) ois.readObject() d.setTime(99999999999L) clonesheep.setAge(9) sheep.setName(' ') System.out.println(sheep) System.out.println(sheep.getAge()) System.out.println(sheep.getName()) System.out.println(sheep.getBirthday()) System.out.println(clonesheep) System.out.println(clonesheep.getAge()) System.out.println(clonesheep.getName()) System.out.println(clonesheep.getBirthday()) } }