原型模式

原型模式

原型模式其实就是拷贝,假设已知对象A,对象B为 A的拷贝,那么B应该具有和A一样的数据。我们还是以造人为例。

(1)  浅克隆

Person.java

package prototype03;

 

import java.util.List;

 

public class Person implements Cloneable{

    private String name = null;

    private int age = 0;

    private String sex = null;

    private List<String> friends = null;

   

    public List<String> getFriends() {

       return friends;

    }

 

    public void setFriends(List<String> friends) {

       this.friends = friends;

    }

 

    public String getName() {

       return name;

    }

   

    public void setName(String name) {

       this.name = name;

    }

   

    public int getAge() {

       return age;

    }

   

    public void setAge(int age) {

       this.age = age;

    }

   

    public String getSex() {

       return sex;

    }

   

    public void setSex(String sex) {

       this.sex = sex;

    }

   

    public Person clone(){

       try {

           return (Person)super.clone();

       } catch (CloneNotSupportedException e) {

           e.printStackTrace();

           return null;

       }

    }

}

先分析一下这个类,首先Person.java实现了Cloneable接口,关于Cloneable接口的详细信息请自己补充,总之,我们在这里只需要知道该接口里面有一个clone方法,而Person类里面也重写了clone方法,其中clone方法也是Person.java的核心方法,原型模式也是通过clone来实现的。

我们先来看一下运行结果,看一看Person.java是如何实现自身复制的

package prototype03;

import java.util.ArrayList;

import java.util.List;

public class MainClass {

         public static void main(String[] args) {

                  Person person1 = new Person();

                  List<String> friends = new ArrayList<String>();

       

                  friends.add("james");

                  friends.add("Yao");

                 

                  person1.setFriends(friends);

                 

                 

                  Person person2 = person1.clone();

                 

                  System.out.println(person1.getFriends());

                  System.out.println(person2.getFriends());

                 

                  friends.add("Mike");

                  person1.setFriends(friends);

                 

                  System.out.println(person2.getFriends());

         }

}

运行结果:

[james, Yao]

[james, Yao]

[james, Yao, Mike]

 

对于运行结果,有些同学肯定会有疑惑,为什么person2的friends里面会包含Mike呢?我们 在程序中明明修改的是person1,这是为什么呢?其实这里牵扯到了内存的相关知识,这里不便详述,请自行到网上搜索,但是这并不影响我们讲解原型模式,你只要知道,这种是浅克隆就可以了。并且请带着这个疑问,一起来了解深克隆是怎样的吧。

(2)  深克隆

话不多少,先贴代码。

Person.java

package prototype04;

import java.util.ArrayList;

import java.util.List;

public class Person implements Cloneable{

         private String name = null;

         private int age = 0;

         private String sex = null;

         private List<String> friends = null;

        

         public List<String> getFriends() {

                  return friends;

         }

         public void setFriends(List<String> friends) {

                  this.friends = friends;

         }

         public String getName() {

                  return name;

         }

        

         public void setName(String name) {

                  this.name = name;

         }

        

         public int getAge() {

                  return age;

         }

        

         public void setAge(int age) {

                  this.age = age;

         }

        

         public String getSex() {

                  return sex;

         }

        

         public void setSex(String sex) {

                  this.sex = sex;

         }

        

         public Person clone(){

                  try {

                          Person person = (Person)super.clone();

                          List<String> friends = new ArrayList<String>();

                          for(String friend:this.getFriends()){

                                   friends.add(friend);

                          }

                          person.setFriends(friends);

                          return person;

                  } catch (CloneNotSupportedException e) {

                          e.printStackTrace();

                          return null;

                  }

         }

}

测试程序:

package prototype04;

import java.util.ArrayList;

import java.util.List;

//深克隆,完全克隆所有的属性,引用的对象也完全的重新new了一遍

public class MainClass {

         public static void main(String[] args) {

                  Person person1 = new Person();

                  List<String> friends = new ArrayList<String>();

       

                  friends.add("james");

                  friends.add("Yao");

                 

                  person1.setFriends(friends);

                 

                 

                  Person person2 = person1.clone();

                 

                  System.out.println(person1.getFriends());

                  System.out.println(person2.getFriends());

                 

                  friends.add("Mike");

                  person1.setFriends(friends);

                 

                  System.out.println(person1.getFriends());

                  System.out.println(person2.getFriends());

         }

}

测试结果:

[james, Yao]

[james, Yao]

[james, Yao, Mike]

[james, Yao]

OK,看完了运行结果,估计会有一种顿然开悟的感觉,其实我们的代码只改了几句,就是我们在浅克隆的基础上,添加了下面几句

List<String> friends = new ArrayList<String>();

                          for(String friend:this.getFriends()){

                                   friends.add(friend);

                          }

                          person.setFriends(friends);

我们重新new了ArrayList,也就是说如果对象A中的属性包含其他的对象(自定义对象、集合……),那么浅克隆仅仅是把对象的引用给复制了,而不会重新的构造出一个新的对象。但是深克隆则会把A完完全全的给重新构造一遍,包括A里面所有的属性,这就是两者的区别。

原文地址:https://www.cnblogs.com/magicy/p/4631792.html