Javaのデザインパターン - プロトタイプ(ドライ)

 23デザインパターンの深さを説明するために、デザインパターンであり、最終的に各平面の分析に努め。プロトタイプ - ADOは、第2の設計パターンを開始しました。

まず、なぜプロトタイプモデルを持っています

 クラスがクローンに必要なとき、私たちは常に新しいオブジェクトをしたくない、その後、一つ一つは、属性値を設定します。今回は、の必要性を持っています

効率的なオブジェクトのコピー方法、プロトタイプデザインパターンが出現しました。

 

第二に、プロトタイプのデザインパターンの文言

 プロトタイプデザインパターン:

パブリッククラスパーソン実装Cloneableを { 

プライベート文字列のuserName;

プライベート文字列のセックス。

プライベートint型の年齢;

パブリック文字列getUserNameは(){
ユーザー名を返します。
}

公共ボイドsetUserName(文字列のuserName){
this.userName = userNameに。
}

パブリック文字列getSex(){
戻り性別;
}

公共ボイドsetSex(文字列性別){
this.sex =セックス。
}

公共INT getAge(){
戻り年齢;
}

公共ボイドsetAge(int型の年齢){
this.age =年齢。
}

@Override
保護された人のクローン()CloneNotSupportedException {スロー
人の人物=(人物)super.cloneを()。
人を返します。
}

@Override
公共の文字列のtoString(){
リターン"人{" +
"のuserName = '" + userNameに+ '\'' +
"性別= '" +性別+ '\'' +
」、年齢= "+年齢+
「}」。
}
}
公共の静的な無効メイン(文字列[]引数)はCloneNotSupportedException {スロー
人物P =新しい人を()。
p.setAge(19)。
p.setUserName( "小明");
p.setSex( "男");
人物P1 = p.clone()。

System.out.println(p.hashCode())。
System.out.println(p1.hashCode())。

p.setAge(12)。

System.out.println(P)。
System.out.println(P1)。
}
执行结果

  

 

 プロトタイプの実装、Personクラス、実装Cloneableインタフェースとcloneメソッド缶をオーバーライドします。

 増加は人では基本的なタイプではなく、また、プロパティの文字列型は、状況はあなたに事故を作ればすべてが、しかし、非常に素晴らしいと思われます。

 1、シャローコピー

パブリッククラスパーソン実装Cloneableを{ 

プライベート文字列のuserName;

プライベート文字列のセックス。

プライベートint型の年齢;

民間の息子の息子。

公共の息子getSon(){
リターンの息子。
}

公共ボイドsetSon(SON息子){
this.son =息子。
}

パブリック文字列getUserNameは(){
ユーザー名を返します。
}

公共ボイドsetUserName(文字列のuserName){
this.userName = userNameに。
}

パブリック文字列getSex(){
戻り性別;
}

公共ボイドsetSex(文字列性別){
this.sex =セックス。
}

公共INT getAge(){
年齢を返します。
}

公共ボイドsetAge(int型の年齢){
this.age =年齢。
}

@Overrideは、
人のクローンを()CloneNotSupportedException {スロー保護された
人物の人物=(人物)super.cloneを()。
人を返します。
}

@Override
公共の文字列のtoString(){
リターン"人{" +
"のuserName = '" + userNameに+ '\'' +
"性別= '" +性別+ '\'' +
」、年齢= "+年齢+
"息子=" +息子+
'}';
}
}
パブリッククラス息子 { 

プライベート文字列sonName。

パブリック文字列getSonName(){
sonNameを返します。
}

公共ボイドsetSonName(文字列sonName){
this.sonName = sonName。
}

@Override
パブリック文字列のtoString(){
リターン"息子{" +
"sonName = '" + sonName + '\'' +
'}'。
}
}
Testクラス{公共
メインボイドのpublic static(文字列[]引数){CloneNotSupportedExceptionスロー
人新しい新しいP =人を();
p.setAge(19);
p.setUserName( "ボブ");
p.setSex( "M")。
=新しい新しい息子息子息子();
son.setSonName( "暁明の子");
p.setSon(息子);
人物P1 = p.clone();

System.out.printlnは(p.hashCode());
システム。 out.printlnを(p1.hashCode());

p1.getSon()setSonName( "ファラオ子供隣");.
p1.setAge(12)

のSystem.out.println(P-);
System.out.printlnは( P1);
}
}
結果は以下の通りであります

  

 では、なぜこのような結果が起こることができますか?

 因为clone方法并不能穿透到son,也就是p和p1公用了son对象(p1对象对son的clone只是copy了指针,并没有完全copy,也就是浅拷贝),所以p和p1同时输出的“隔壁老王的孩子”。

 

 

  如果我们希望实现完整的clone,该如何处理呢?我们需要深拷贝。

 2,深拷贝

  1)套娃式深拷贝

  我们在浅拷贝的基础上修改,修改部分笔者用红色标识。

public class Person implements Cloneable {

private String userName;

private String sex;

private int age;

private Son son;

public Son getSon() {
return son;
}

public void setSon(Son son) {
this.son = son;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public String getSex() {
return sex;
}

public void setSex(String sex) {
this.sex = sex;
}

public int getAge() {
return age;
}

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

@Override
protected Person clone() throws CloneNotSupportedException {
Person person = (Person) super.clone();
person.setSon(person.getSon().clone());
return person;
}

@Override
public String toString() {
return "Person{" +
"userName='" + userName + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
", son=" + son +
'}';
}
}

public class Son implements Cloneable {

private String sonName;

public String getSonName() {
return sonName;
}

public void setSonName(String sonName) {
this.sonName = sonName;
}

@Override
public String toString() {
return "Son{" +
"sonName='" + sonName + '\'' +
'}';
}

@Override
protected Son clone() throws CloneNotSupportedException {
return (Son) super.clone();
}
}
我们再来看结果:

  

  很显然,得到了我们期望的结果,像不像套娃?

  2)序列化深拷贝

  首先改造Person

public class Person implements Serializable {

private String userName;

private String sex;

private int age;

private Son son;

public Son getSon() {
return son;
}

public void setSon(Son son) {
this.son = son;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public String getSex() {
return sex;
}

public void setSex(String sex) {
this.sex = sex;
}

public int getAge() {
return age;
}

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

@Override
public String toString() {
return "Person{" +
"userName='" + userName + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
", son=" + son +
'}';
}
}
接着,改造Son
public class Son implements Serializable {

private String sonName;

public String getSonName() {
return sonName;
}

public void setSonName(String sonName) {
this.sonName = sonName;
}

@Override
public String toString() {
return "Son{" +
"sonName='" + sonName + '\'' +
'}';
}

}
Main方法
public class Test {
public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
Person p = new Person();
p.setAge(19);
p.setUserName("小明");
p.setSex("男");
Son son = new Son();
son.setSonName("小明的孩子");
p.setSon(son);

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

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


System.out.println(p.hashCode());
System.out.println(p1.hashCode());

p1.getSon().setSonName("隔壁老王的孩子");
p1.setAge(12);

System.out.println(p);
System.out.println(p1);
}
}
来看看输出结果:

  

 很显然,得到了我们期望的结果。

 当然,可以把序列化过程封装到Person中。没有了套娃,又可以欢乐玩耍了。

 总结:每一种拷贝都有自己的应用场景,要看具体的业务场景。

 

おすすめ

転載: www.cnblogs.com/x-j-p/p/12381088.html