设计模式笔记之四(原型模式)

原型模式

原型模式就是需要创建多个实例的时候,以一个为原型,其他实例复制/克隆这个原型来获得相似的实例。

我们的实验室最近研究这个模式还是因为市场的原因,市场上由于长久以来的习俗和政策,对女人的需求比较大,所有我们就的扩大女人的生产线,但是由于资金的原因,我们不能投入硬件成本只能改进我们的方法。

首先我们得分析女人的构成:

class NvRen {
    private String name;
    private String head;
    private String body;
    private String type;

    public NvRen(String name, String head, String body, String type) {
        this.name = name;
        this.head = head;
        this.body = body;
        this.type = type;
    }
}

我们以前生产女人的时候我们把预设好的名字,头型,身型,类型在创建女人的时候传入(好吧,我承认女人很难懂,但我们春秋笔法下~~)。

public class Prototype {

    public static void main(String[] args) {
        NvRen nvren1 = new NvRen("小责圆","瓜子脸","葫芦型","气质高雅型");
        NvRen nvren2 = new NvRen("松岛丰","圆脸","葫芦型","邻家御姐型");
        NvRen nvren3 = new NvRen("饭到爱","瓜子脸","葫芦型","可爱型");
        NvRen nvren4 = new NvRen("罗玉风","面瓜脸","水桶型","恶心型");
    }
}

研究了很久,我们的市场部经理终于有了想法:由于高富帅客户不需要我们的产品,现在需求我们产品的客户基本上都属于丑矮穷搓撸的类型,他们对我们的产品也没有多少要求,只要有不同名字就行,我觉得我们可以批量生产女人,出厂的时候再给他们设置下不同的名字就行了,所以我们更改了我们的女人类:

class NvRen implements Cloneable {
    private String name;
    private String head;
    private String body;
    private String type;

    public NvRen(String name, String head, String body, String type) {
        this.name = name;
        this.head = head;
        this.body = body;
        this.type = type;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    protected NvRen clone() {
        NvRen nr = null;
        try {
            nr = (NvRen) super.clone();
        } catch (CloneNotSupportedException e) {
            nr = new NvRen(this.name, this.head, this.body, this.type);
        }
        return nr;
    }
}

现在我们就可以很Happy的批量生产了

public class Prototype {

    public static void main(String[] args) {
        NvRen nvren1 = new NvRen("小责圆", "瓜子脸", "葫芦型", "气质高雅型");
        NvRen nvren2 = nvren1.clone();
        nvren2.setName("松岛丰");
        NvRen nvren3 = nvren1.clone();
        nvren3.setName("饭到爱");
        NvRen nvren4 = nvren1.clone();
        // nvren4.setName("罗玉风"); //这个实在不好卖,即使只有名字和其他的不一样
        nvren4.setName("苍老师");
    }
}

当我们的产品投放到市场的时候,却很是悲摧了,因为他们投诉我们生产的女人只有一个却顶着不同的名字到处卖。

我们只能再次研究,最后发现我们的一个工程师为了更加方便的生产,对我们的女人类作了些改变:

class RouTi {
    private String head;
    private String body;
    private String type;
    public RouTi(String head, String body, String type) {
        this.head = head;
        this.body = body;
        this.type = type;
    }
}

class NvRen implements Cloneable {
    private String name;
    private RouTi routi;

    public NvRen(String name, String head, String body, String type) {
        this.name = name;
        this.routi = new RouTi(head, body, type);
    }
    private NvRen(String name, RouTi routi) {
        this.name = name;
        this.routi = routi;
    }
    public void setName(String name) {
        this.name = name;
    }
    public RouTi getRouTi() {
        return this.routi;
    }
    @Override
    protected NvRen clone() {
        NvRen nr = null;
        try {
            nr = (NvRen) super.clone();
        } catch (CloneNotSupportedException e) {
            nr = new NvRen(this.name, this.routi);
        }
        return nr;
    }
}

我们做了一些测试发现这些女人虽然有不同的名字,但是她们共用一个肉体

public class Prototype {

    public static void main(String[] args) {
        NvRen nvren1 = new NvRen("小责圆", "瓜子脸", "葫芦型", "气质高雅型");
        System.out.println(nvren1.getRouTi().toString());
        NvRen nvren2 = nvren1.clone();
        nvren2.setName("松岛丰");
        System.out.println(nvren2.getRouTi().toString());
        NvRen nvren3 = nvren1.clone();
        nvren3.setName("饭到爱");
        System.out.println(nvren3.getRouTi().toString());
        NvRen nvren4 = nvren1.clone();
        // nvren4.setName("罗玉风"); //这个实在不好卖,即使只有名字和其他的不一样
        nvren4.setName("苍老师");
        System.out.println(nvren4.getRouTi().toString());
    }
}


//------> output
//com.pattern.now.RouTi@1fc4bec
//com.pattern.now.RouTi@1fc4bec
//com.pattern.now.RouTi@1fc4bec
//com.pattern.now.RouTi@1fc4bec

经研究发现:当我们使用clone方法的时候,我们做的只是浅克隆,浅克隆只会复制值类型的属性,引用类型的属性只会复制其引用(即指针)而不会复制整个引用的对象。

所以我们要克隆女人的时候还得克隆肉体:

class RouTi implements Cloneable {
    private String head;
    private String body;
    private String type;

    public RouTi(String head, String body, String type) {
        this.head = head;
        this.body = body;
        this.type = type;
    }

    @Override
    protected RouTi clone() {
        RouTi rt = null;
        try {
            rt = (RouTi) super.clone();
        } catch (CloneNotSupportedException e) {
            rt = new RouTi(this.head, this.body, this.type);
        }
        return rt;
    }
}

class NvRen implements Cloneable {
    private String name;
    private RouTi routi;

    public NvRen(String name, String head, String body, String type) {
        this.name = name;
        this.routi = new RouTi(head, body, type);
    }

    private NvRen(String name, RouTi routi) {
        this.name = name;
        this.routi = routi;
    }

    public void setName(String name) {
        this.name = name;
    }

    public RouTi getRouTi() {
        return this.routi;
    }

    @Override
    protected NvRen clone() {
        NvRen nr = new NvRen(this.name, this.routi.clone());
        return nr;
    }
}

这时我们就能得到正确的结果:不同的女人有不同的肉体

//--->output
//com.pattern.now.RouTi@1fc4bec
//com.pattern.now.RouTi@dc8569
//com.pattern.now.RouTi@1bab50a
//com.pattern.now.RouTi@c3c749

这是我们的一个宅男工程师提出一个问题: 当我们的的肉体类种新加一个属性叫likeWho,并且 值是女人类:

private NvRen likeWho;

哥只能说:遇到这种情况,要么是你的女人类设计得有问题,要么就只能放弃原型模式。

 

posted @ 2013-05-10 14:48  biglaojiang  阅读(547)  评论(1编辑  收藏  举报