原型模式

原型模式

克隆羊的问题

 

 

传统方案解决

package com.sky.prototype;

/**
 * 羊
 */
public class Sheep {

    private String name; // 姓名
    private int age; // 年龄
    private String color; // 颜色

    public Sheep(String name, int age, String color) {
        this.name = name;
        this.age = age;
        this.color = color;
    }

    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 getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    @Override
    public String toString() {
        return "Sheep{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", color='" + color + '\'' +
                '}';
    }
}

package com.sky.prototype;

/**
 * 客户端
 */
public class Client {

    public static void main(String[] args) {

        // 传统方法
        Sheep sheep1 = new Sheep("tom", 1, "白色");

        Sheep sheep2 = new Sheep(sheep1.getName(), sheep1.getAge(), sheep1.getColor());
        Sheep sheep3 = new Sheep(sheep1.getName(), sheep1.getAge(), sheep1.getColor());
        Sheep sheep4 = new Sheep(sheep1.getName(), sheep1.getAge(), sheep1.getColor());
        Sheep sheep5 = new Sheep(sheep1.getName(), sheep1.getAge(), sheep1.getColor());
        Sheep sheep6 = new Sheep(sheep1.getName(), sheep1.getAge(), sheep1.getColor());
        // ...

        System.out.println(sheep1);
        System.out.println(sheep2);
        System.out.println(sheep3);
        System.out.println(sheep4);
        System.out.println(sheep5);
        System.out.println(sheep6);

    }

}

运行结果:
Sheep{name='tom', age=1, color='白色'}
Sheep{name='tom', age=1, color='白色'}
Sheep{name='tom', age=1, color='白色'}
Sheep{name='tom', age=1, color='白色'}
Sheep{name='tom', age=1, color='白色'}
Sheep{name='tom', age=1, color='白色'}
View Code

传统方案的优缺点

 

原型模式基本介绍:

 

 

 

 

使用原型模式解决克隆羊问题

 

package com.sky.prototype.improve;

/**
 * 羊
 */
public class Sheep implements Cloneable{

    private String name; // 姓名
    private int age; // 年龄
    private String color; // 颜色

    public Sheep(String name, int age, String color) {
        this.name = name;
        this.age = age;
        this.color = color;
    }

    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 getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    @Override
    public String toString() {
        return "Sheep{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", color='" + color + '\'' +
                '}';
    }

    // 重写clone方法
    @Override
    protected Object clone() {

        Sheep sheep = null;
        try {
            sheep = (Sheep)super.clone();
        } catch (CloneNotSupportedException e) {
            System.out.println(e.getMessage());
        }
        return sheep;
    }
}

package com.sky.prototype.improve;


/**
 * 客户端
 */
public class Client {

    public static void main(String[] args) {

        System.out.println("使用原型模式进行对象的创建");
        // 传统方法
        Sheep sheep1 = new Sheep("tom", 1, "白色");

        Sheep sheep2 = (Sheep) sheep1.clone();
        Sheep sheep3 = (Sheep) sheep1.clone();
        Sheep sheep4 = (Sheep) sheep1.clone();
        Sheep sheep5 = (Sheep) sheep1.clone();
        Sheep sheep6 = (Sheep) sheep1.clone();
        Sheep sheep7 = (Sheep)sheep6.clone();
        // ...

        System.out.println(sheep1);
        System.out.println(sheep2);
        System.out.println(sheep3);
        System.out.println(sheep4);
        System.out.println(sheep5);
        System.out.println(sheep6);
        System.out.println(sheep7);

        System.out.println();

        System.out.println("sheep1 hashcode : " + sheep1.hashCode());
        System.out.println("sheep2 hashcode : " + sheep2.hashCode());
        System.out.println("sheep3 hashcode : " + sheep3.hashCode());
        System.out.println("sheep4 hashcode : " + sheep4.hashCode());
        System.out.println("sheep5 hashcode : " + sheep5.hashCode());
        System.out.println("sheep6 hashcode : " + sheep6.hashCode());
        System.out.println("sheep7 hashcode : " + sheep7.hashCode());

    }


}

使用原型模式进行对象的创建
Sheep{name='tom', age=1, color='白色'}
Sheep{name='tom', age=1, color='白色'}
Sheep{name='tom', age=1, color='白色'}
Sheep{name='tom', age=1, color='白色'}
Sheep{name='tom', age=1, color='白色'}
Sheep{name='tom', age=1, color='白色'}
Sheep{name='tom', age=1, color='白色'}

sheep1 hashcode : 356573597
sheep2 hashcode : 1735600054
sheep3 hashcode : 21685669
sheep4 hashcode : 2133927002
sheep5 hashcode : 1836019240
sheep6 hashcode : 325040804
sheep7 hashcode : 1173230247
View Code

 

原型模式中的浅拷贝和深拷贝

浅拷贝

 

 

package com.sky.prototype.simple;

/**
 * 羊 浅拷贝
 */
public class Sheep implements Cloneable{

    private String name; // 姓名
    private int age; // 年龄
    private String color; // 颜色
    public Sheep friend; // 这只羊有一个朋友

    public Sheep(String name, int age, String color) {
        this.name = name;
        this.age = age;
        this.color = color;
    }

    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 getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    @Override
    public String toString() {
        return "Sheep{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", color='" + color + '\'' +
                '}';
    }

    // 重写clone方法
    @Override
    protected Object clone() {

        Sheep sheep = null;
        try {
            sheep = (Sheep)super.clone();
        } catch (CloneNotSupportedException e) {
            System.out.println(e.getMessage());
        }
        return sheep;
    }
}


package com.sky.prototype.simple;


/**
 * 客户端
 */
public class Client {

    public static void main(String[] args) {

        System.out.println("使用原型模式进行对象的创建");
        // 传统方法
        Sheep sheep1 = new Sheep("tom", 1, "白色");
        sheep1.friend = new Sheep("Jack", 2, "黑色");

        Sheep sheep2 = (Sheep) sheep1.clone();
        Sheep sheep3 = (Sheep) sheep1.clone();
        Sheep sheep4 = (Sheep) sheep1.clone();
        Sheep sheep5 = (Sheep) sheep1.clone();
        Sheep sheep6 = (Sheep) sheep1.clone();
        Sheep sheep7 = (Sheep)sheep6.clone();
        // ...

        System.out.println(sheep1);
        System.out.println(sheep2);
        System.out.println(sheep3);
        System.out.println(sheep4);
        System.out.println(sheep5);
        System.out.println(sheep6);
        System.out.println(sheep7);

        System.out.println();

        System.out.println("sheep1 hashcode : " + sheep1.hashCode() + " sheep1 hashcode : " + sheep1.friend.hashCode());
        System.out.println("sheep2 hashcode : " + sheep2.hashCode() + " sheep2 hashcode : " + sheep1.friend.hashCode());
        System.out.println("sheep3 hashcode : " + sheep3.hashCode() + " sheep3 hashcode : " + sheep1.friend.hashCode());
        System.out.println("sheep4 hashcode : " + sheep4.hashCode() + " sheep4 hashcode : " + sheep1.friend.hashCode());
        System.out.println("sheep5 hashcode : " + sheep5.hashCode() + " sheep5 hashcode : " + sheep1.friend.hashCode());
        System.out.println("sheep6 hashcode : " + sheep6.hashCode() + " sheep6 hashcode : " + sheep1.friend.hashCode());
        System.out.println("sheep7hashcode : " + sheep7.hashCode() + " sheep7 hashcode : " + sheep1.friend.hashCode());




    }
}

使用原型模式进行对象的创建
Sheep{name='tom', age=1, color='白色'}
Sheep{name='tom', age=1, color='白色'}
Sheep{name='tom', age=1, color='白色'}
Sheep{name='tom', age=1, color='白色'}
Sheep{name='tom', age=1, color='白色'}
Sheep{name='tom', age=1, color='白色'}
Sheep{name='tom', age=1, color='白色'}

sheep1 hashcode : 356573597 sheep1 hashcode : 1735600054
sheep2 hashcode : 21685669 sheep2 hashcode : 1735600054
sheep3 hashcode : 2133927002 sheep3 hashcode : 1735600054
sheep4 hashcode : 1836019240 sheep4 hashcode : 1735600054
sheep5 hashcode : 325040804 sheep5 hashcode : 1735600054
sheep6 hashcode : 1173230247 sheep6 hashcode : 1735600054
sheep7hashcode : 856419764 sheep7 hashcode : 1735600054
View Code

深拷贝

 

 

package com.sky.prototype.deepclone;

import java.io.Serializable;

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;
    }

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

package com.sky.prototype.deepclone;

import java.io.*;

public class DeepPrototype implements Serializable, Cloneable {

    public String name; // 属性
    public DeepCloneableTarget deepCloneableTarget; // 引用类型

    public DeepPrototype() {
        super();
    }

    // 深拷贝 - 方式一 使用clone方法
    @Override
    protected Object clone() throws CloneNotSupportedException {

        Object deep = null;
        // 这里完成对基本数据类型(属性)和String类型的克隆
        deep = super.clone();
        // 对引用类型的属性,进行单独的处理
        DeepPrototype deepPrototype = (DeepPrototype) deep;
        // 对引用对象进行单独的拷贝
        deepPrototype.deepCloneableTarget = (DeepCloneableTarget) deepCloneableTarget.clone();

        return deepPrototype;
    }

    // 深拷贝 方式二 通过对象的序列化实现(推荐)
    public Object deepClone() {

        // 创建流对象 输入流 输出流
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;
        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;

        try {

            //序列化
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(this); // 当前这个对象以对象流的方式输出

            // 反序列化
            bis = new ByteArrayInputStream(bos.toByteArray());
            ois = new ObjectInputStream(bis);
            DeepPrototype copyObj = (DeepPrototype) ois.readObject();

            return copyObj;
        } catch (Exception e) {

            e.printStackTrace();
            return null;

        } finally {
            // 关闭流
            try {
                ois.close();
                bis.close();
                oos.close();
                bos.close();
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }

    }

}

package com.sky.prototype.deepclone;

public class Client {

    public static void main(String[] args) throws Exception{
        DeepPrototype p = new DeepPrototype();
        p.name = "宋江";
        p.deepCloneableTarget = new DeepCloneableTarget("大牛","小牛");

        // 方式一 完成深拷贝
        DeepPrototype p2 = (DeepPrototype)p.clone();
        // 看看内存地址是不是一样的
        System.out.println("p.name = " + p.name + "p.deepCloneableTarget = "+ p.deepCloneableTarget.hashCode());
        System.out.println("p2.name = " + p.name + "p2.deepCloneableTarget = "+ p2.deepCloneableTarget.hashCode());


        // 方式二 完成深拷贝 使用流的方式
//        DeepPrototype p2 = (DeepPrototype) p.deepClone();
//        System.out.println("p.name = " + p.name + "p.deepCloneableTarget = "+ p.deepCloneableTarget.hashCode());
//        System.out.println("p2.name = " + p.name + "p2.deepCloneableTarget = "+ p2.deepCloneableTarget.hashCode());
    }
}

运行方式一:
p.name = 宋江p.deepCloneableTarget = 356573597
p2.name = 宋江p2.deepCloneableTarget = 1735600054
运行方式二:
p.name = 宋江p.deepCloneableTarget = 621009875
p2.name = 宋江p2.deepCloneableTarget = 1329552164
View Code

原型模式的注意事项和细节

 

posted on 2022-12-01 18:54  ~码铃薯~  阅读(17)  评论(0编辑  收藏  举报

导航