java设计模式之原型模式

原型模式:通过原型实例创建新的对象,就不再需要关心这个实例本身的类型,只要实现了克隆自身的方法,就可以通过这个方法来获取新的对象,而无须再去通过new来创建。

原型模式有以下几种方式:简单形式(new一个对象),浅克隆,深克隆

前面两种方式比较简单,我直接用深克隆来实现,深克隆是通过流的方式来实现兑现对象的克隆。

猴子类:

package prototype;

import java.io.*;
import java.util.Date;

public class Monkey implements Cloneable,Serializable {

    //身高
    private int height;
    //体重
    private int weight;
    //生日
    private Date birthDate;
    //金箍棒
    private GoldRingedStaff staff;

    public Monkey(Date birthDate, GoldRingedStaff staff) {
        this.birthDate = birthDate;
        this.staff = staff;
    }

    @Override
    protected Object clone(){
        Monkey monkey = null;
        try{
            monkey = (Monkey)super.clone();
        } catch (CloneNotSupportedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            return monkey;
        }
    }
    public Object deepClone(){
        try{
            //将对象写到流里
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(this);
            //从流里读出来
            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis);
            return ois.readObject();
        }catch (Exception e){
            return null;
        }
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }

    public Date getBirthDate() {
        return birthDate;
    }

    public void setBirthDate(Date birthDate) {
        this.birthDate = birthDate;
    }

    public GoldRingedStaff getStaff() {
        return staff;
    }

    public void setStaff(GoldRingedStaff staff) {
        this.staff = staff;
    }
}
View Code

金箍棒类:

package prototype;

import java.io.Serializable;

public class GoldRingedStaff implements Serializable {

    private float height = 100.0f;
    private float diameter = 10.0f;

    /**
     * 增长行为,每次调用长度和半径增加一倍
     */
    public void grow(){
        this.diameter *= 2;
        this.height *= 2;
    }
    /**
     * 缩小行为,每次调用长度和半径减少一半
     */
    public void shrink(){
        this.diameter /= 2;
        this.height /= 2;
    }

}
View Code

客户端类:

package prototype;

import java.util.Date;

public class Client {

    private Monkey monkey = new Monkey(new Date(),new GoldRingedStaff());
    public void change(){
        //克隆大圣本尊
        Monkey copyMonkey = (Monkey) monkey.deepClone();
        System.out.println("大圣本尊的生日是:" + monkey.getBirthDate());
        System.out.println("克隆的大圣的生日是:" + monkey.getBirthDate());
        System.out.println("大圣本尊跟克隆的大圣是否为同一个对象 " + (monkey == copyMonkey));
        System.out.println("大圣本尊持有的金箍棒 跟 克隆的大圣持有的金箍棒是否为同一个对象? " + (monkey.getStaff() == copyMonkey.getStaff()));
    }

    public static void main(String[] args) {
        Client client = new Client();
        client.change();
    }
}
View Code

运行结果:

大圣本尊的生日是:Tue Aug 28 22:27:35 CST 2018
克隆的大圣的生日是:Tue Aug 28 22:27:35 CST 2018
大圣本尊跟克隆的大圣是否为同一个对象 false
大圣本尊持有的金箍棒 跟 克隆的大圣持有的金箍棒是否为同一个对象? false

相关推荐