问题 :现有一只羊 tom ,age =1 ,color = white 编写程序创建和tom养属性完全相同的10只羊

原型模式:用原型实例指定创建对象的种类,并且通过拷贝原型,创建新的对象

传统方法

  1. public static void main(String[] args) {
  2. // TODO Auto-generated method stub
  3. //传统的方法
  4. Sheep sheep = new Sheep("tom", 1, "白色");
  5. Sheep sheep2 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());
  6. Sheep sheep3 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());
  7. Sheep sheep4 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());
  8. Sheep sheep5 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());
  9. //....
  10. System.out.println(sheep);
  11. System.out.println(sheep2);
  12. System.out.println(sheep3);
  13. System.out.println(sheep4);
  14. System.out.println(sheep5);
  15. //...
  16. }

clone

Object 有一个clone方法

  1. public static void main(String[] args) {
  2. System.out.println("原型模式完成对象的创建");
  3. // TODO Auto-generated method stub
  4. Sheep sheep = new Sheep("tom", 1, "白色");
  5. sheep.friend = new Sheep("jack", 2, "黑色");
  6. Sheep sheep2 = (Sheep)sheep.clone(); //克隆
  7. Sheep sheep3 = (Sheep)sheep.clone(); //克隆
  8. Sheep sheep4 = (Sheep)sheep.clone(); //克隆
  9. Sheep sheep5 = (Sheep)sheep.clone(); //克隆
  10. System.out.println("sheep2 =" + sheep2 + "sheep2.friend=" + sheep2.friend.hashCode());
  11. System.out.println("sheep3 =" + sheep3 + "sheep3.friend=" + sheep3.friend.hashCode());
  12. System.out.println("sheep4 =" + sheep4 + "sheep4.friend=" + sheep4.friend.hashCode());
  13. System.out.println("sheep5 =" + sheep5 + "sheep5.friend=" + sheep5.friend.hashCode());
  14. }

implements Cloneable 重写clone方法

  1. public class Sheep implements Cloneable {
  2. private String name;
  3. private int age;
  4. private String color;
  5. private String address = "蒙古羊";
  6. public Sheep friend; //是对象, 克隆是会如何处理
  7. public Sheep(String name, int age, String color) {
  8. super();
  9. this.name = name;
  10. this.age = age;
  11. this.color = color;
  12. }
  13. public String getName() {
  14. return name;
  15. }
  16. public void setName(String name) {
  17. this.name = name;
  18. }
  19. public int getAge() {
  20. return age;
  21. }
  22. public void setAge(int age) {
  23. this.age = age;
  24. }
  25. public String getColor() {
  26. return color;
  27. }
  28. public void setColor(String color) {
  29. this.color = color;
  30. }
  31. @Override
  32. public String toString() {
  33. return "Sheep [name=" + name + ", age=" + age + ", color=" + color + ", address=" + address + "]";
  34. }
  35. //克隆该实例,使用默认的clone方法来完成
  36. @Override
  37. protected Object clone() {
  38. Sheep sheep = null;
  39. try {
  40. sheep = (Sheep)super.clone();
  41. } catch (Exception e) {
  42. // TODO: handle exception
  43. System.out.println(e.getMessage());
  44. }
  45. // TODO Auto-generated method stub
  46. return sheep;
  47. }
  48. }

源码使用 spring beanxml scope = “prototype”

浅拷贝

克隆对象里面的对象 直接指向原本的地址

深拷贝

重写clone

对象序列化

  1. public class DeepProtoType implements Serializable, Cloneable{
  2. public String name; //String 属性
  3. public DeepCloneableTarget deepCloneableTarget;// 引用类型
  4. public DeepProtoType() {
  5. super();
  6. }
  7. //深拷贝 - 方式 1 使用clone 方法
  8. @Override
  9. protected Object clone() throws CloneNotSupportedException {
  10. Object deep = null;
  11. //这里完成对基本数据类型(属性)和String的克隆
  12. deep = super.clone();
  13. //对引用类型的属性,进行单独处理
  14. DeepProtoType deepProtoType = (DeepProtoType)deep;
  15. deepProtoType.deepCloneableTarget = (DeepCloneableTarget)deepCloneableTarget.clone();
  16. // TODO Auto-generated method stub
  17. return deepProtoType;
  18. }
  19. //深拷贝 - 方式2 通过对象的序列化实现 (推荐)
  20. public Object deepClone() {
  21. //创建流对象
  22. ByteArrayOutputStream bos = null;
  23. ObjectOutputStream oos = null;
  24. ByteArrayInputStream bis = null;
  25. ObjectInputStream ois = null;
  26. try {
  27. //序列化
  28. bos = new ByteArrayOutputStream();
  29. oos = new ObjectOutputStream(bos);
  30. oos.writeObject(this); //当前这个对象以对象流的方式输出
  31. //反序列化
  32. bis = new ByteArrayInputStream(bos.toByteArray());
  33. ois = new ObjectInputStream(bis);
  34. DeepProtoType copyObj = (DeepProtoType)ois.readObject();
  35. return copyObj;
  36. } catch (Exception e) {
  37. // TODO: handle exception
  38. e.printStackTrace();
  39. return null;
  40. } finally {
  41. //关闭流
  42. try {
  43. bos.close();
  44. oos.close();
  45. bis.close();
  46. ois.close();
  47. } catch (Exception e2) {
  48. // TODO: handle exception
  49. System.out.println(e2.getMessage());
  50. }
  51. }
  52. }
  53. }
public class DeepCloneableTarget implements Serializable, Cloneable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private String cloneName;

    private String cloneClass;

    //构造器
    public DeepCloneableTarget(String cloneName, String cloneClass) {
        this.cloneName = cloneName;
        this.cloneClass = cloneClass;
    }

    //因为该类的属性,都是String , 因此我们这里使用默认的clone完成即可
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

原型模式注意事项