原型设计模式(prototype)----快速生产汽车

快速造汽车----原型模式

产汽车很累怎么办?

上一次我们介绍了工厂模式(Factory),即用户可以通过提供具体的车型信息由工厂生产出来返回。

后来竟然发现客户越来越少,工厂也入不敷出,甚至遭到了投诉,口碑极差,即将砸大门倒闭,这是为啥了呢?奥,原来是工厂产汽车太慢了,豪门大佬一下子要100台劳斯莱斯,我们工人不断从零做起,购买零件,组装轮胎、组装车身、组装发动机…

高工程师来帮忙

组装的太慢了,这时高工程师就想,如果我们此时有一台劳斯莱斯,能够不断拷贝出来新的劳斯莱斯就好了,但是拷贝是需要new出来的,然后不断设计添加属性、进行组装的,这是高工程师拿出了法宝Cloneable接口,只要是实现了此接口的类,均可以拷贝出来同样的新的劳斯莱斯车!!很快,工厂再次站了起来,高工程师也破格升职为高高工程师~~~

哈哈哈,这就是设计模式中原型模式的具体抽象!!!

高工程师的法宝(实现原型模式)

图解法宝(原型模式)

在这里插入图片描述

这时,问题就明白了,我们需要这样拯救工厂:

  1. 我们来设计一个车型,除下设计此车型的所有制作流程以外,我们需要对此车型类实现Cloneable接口、覆写clone()方法。
  2. 生产新的车子时,只需要调用已创建好的车型的clone()方法,造新车即可!!!

高工程师的最初具体实现(浅拷贝)

劳斯莱斯的车型类

package com.design_patterns.prototype.instance;


import com.design_patterns.factory.instance.Car;

public class RollsRoyce implements Car, Cloneable {
    
    
    private String tirName = null;                  //轮胎型号
    private String bodyName = null;             //车身型号
    private String engineName = null;               //发动机型号
    private Information information = null;         //劳斯莱斯车的信息类对象

    public String getTirName() {
    
    
        return tirName;
    }

    public void setTirName(String tirName) {
    
    
        this.tirName = tirName;
    }

    public String getBodyName() {
    
    
        return bodyName;
    }

    public void setBodyName(String bodyName) {
    
    
        this.bodyName = bodyName;
    }

    public String getEngineName() {
    
    
        return engineName;
    }

    public void setEngineName(String engineName) {
    
    
        this.engineName = engineName;
    }

    public Information getInformation() {
    
    
        return information;
    }

    public void setInformation(Information information) {
    
    
        this.information = information;
    }

    @Override
    public void produce() {
    
    
        System.out.println("劳斯莱斯车生产成功!");
    }

    /**
     * 覆写劳斯莱斯车的拷贝方法,默认为父类的clone方法
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
    
    
        return super.clone();
    }

    @Override
    public String toString() {
    
    
        return "RollsRoyce{" +
                "tirName='" + tirName + '\'' +
                ", bodyName='" + bodyName + '\'' +
                ", engineName='" + engineName + '\'' +
                ", information=" + information +
                '}';
    }
}

劳斯莱斯车的生产信息类Information(表示第几辆车)

package com.design_patterns.prototype.instance;

public class Information {
    
    
    private static int amount = 0;              //劳斯莱斯车的生产数量
    public Information(){
    
    
        amount++;
    }

    public static int getAmount() {
    
    
        return amount;
    }

    public static void setAmount(int amount) {
    
    
        Information.amount = amount;
    }

    @Override
    public String toString() {
    
    
        return "劳斯莱斯@num" + amount;
    }
}

生产操作测试类

package com.design_patterns.prototype.instance;

public class Client {
    
    
    public static void main(String[] args) throws Exception{
    
    
        RollsRoyce rollsRoyce = new RollsRoyce();
        rollsRoyce.setTirName("劳斯莱斯轮胎");                //制造轮胎
        rollsRoyce.setBodyName("劳斯莱斯车身");                //制造车身
        rollsRoyce.setEngineName("劳斯莱斯发动机");                  //制造发动机
        rollsRoyce.produce();                           //制造汽车,此为汽车的制作全部过程
        rollsRoyce.setInformation(new Information());

        System.out.println("样本车产生---->" + rollsRoyce + "\n");

        int num = 50;
        RollsRoyce rollsRoyce1 = null;
        while (num > 0){
    
                                                        //生产50辆劳斯莱斯车
            rollsRoyce1 = (RollsRoyce) rollsRoyce.clone();
            System.out.println(rollsRoyce1);
            System.out.println("生产编号: " + rollsRoyce1.hashCode());
            num--;
        }
    }
}

运行结果

劳斯莱斯车生产成功!
样本车产生---->RollsRoyce{
    
    tirName='劳斯莱斯轮胎', bodyName='劳斯莱斯车身', engineName='劳斯莱斯发动机', information=劳斯莱斯@num1}

RollsRoyce{
    
    tirName='劳斯莱斯轮胎', bodyName='劳斯莱斯车身', engineName='劳斯莱斯发动机', information=劳斯莱斯@num1}
生产编号: 1163157884
RollsRoyce{
    
    tirName='劳斯莱斯轮胎', bodyName='劳斯莱斯车身', engineName='劳斯莱斯发动机', information=劳斯莱斯@num1}
生产编号: 1956725890
RollsRoyce{
    
    tirName='劳斯莱斯轮胎', bodyName='劳斯莱斯车身', engineName='劳斯莱斯发动机', information=劳斯莱斯@num1}
生产编号: 356573597
RollsRoyce{
    
    tirName='劳斯莱斯轮胎', bodyName='劳斯莱斯车身', engineName='劳斯莱斯发动机', information=劳斯莱斯@num1}
生产编号: 1735600054
RollsRoyce{
    
    tirName='劳斯莱斯轮胎', bodyName='劳斯莱斯车身', engineName='劳斯莱斯发动机', information=劳斯莱斯@num1}
生产编号: 21685669
......
由于生产50台,数据过多暂列举一部分,生产编号均不同

哇塞,此时我们发现,完全相同的50太劳斯莱斯车几乎瞬间被生产出来了,再也不用辛辛苦苦set、set、set的生产了,生产效率得到了极大的提升,正当老板和客户十分高兴的时候。

高工程师对老板说,这50台劳斯莱斯不能出售了,为了日后工厂的正向发展,必须销毁,这是为啥呢?这时都注意到了劳斯莱斯车车内玻璃窗都统一印着一行小字: information: 劳斯莱斯@num1,为什么车型的编号的都是1呢?明明确定了信息类在实例化时acount都会累加的。

此时高工程师说,事实上我们只有一个Information实例。我们在拷贝劳斯莱斯车的时候使用的是浅拷贝,而Information类为引用数据类型,浅拷贝只能将新的引用数据类型的取值指向原引用数据的地址,不能够重新生产(new)引用数据类型。如果要想实现也生产(new)引用数据类型Information,则必须改进覆写clone()方法,高工程师给出了解决方案…

新的解决方案

高工程师给出了指导方案,将(RollsRoyce类):

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

改进为

@Override
protected Object clone() throws CloneNotSupportedException {
     
     
    RollsRoyce rollsRoyce = (RollsRoyce) super.clone();
    rollsRoyce.information = new Information();            //实例化一个新的Information类对象
    return rollsRoyce;                                  //返回深拷贝后的劳斯莱斯车对象
}

这样就对Information劳斯莱斯车信息的类也进行了生产,再次运行生产劳斯莱斯车的操作…

运行结果

劳斯莱斯车生产成功!
样本车产生---->RollsRoyce{
    
    tirName='劳斯莱斯轮胎', bodyName='劳斯莱斯车身', engineName='劳斯莱斯发动机', information=劳斯莱斯@num1}

RollsRoyce{
    
    tirName='劳斯莱斯轮胎', bodyName='劳斯莱斯车身', engineName='劳斯莱斯发动机', information=劳斯莱斯@num2}
生产编号: 1163157884
RollsRoyce{
    
    tirName='劳斯莱斯轮胎', bodyName='劳斯莱斯车身', engineName='劳斯莱斯发动机', information=劳斯莱斯@num3}
生产编号: 1956725890
RollsRoyce{
    
    tirName='劳斯莱斯轮胎', bodyName='劳斯莱斯车身', engineName='劳斯莱斯发动机', information=劳斯莱斯@num4}
生产编号: 356573597
RollsRoyce{
    
    tirName='劳斯莱斯轮胎', bodyName='劳斯莱斯车身', engineName='劳斯莱斯发动机', information=劳斯莱斯@num5}
生产编号: 1735600054
RollsRoyce{
    
    tirName='劳斯莱斯轮胎', bodyName='劳斯莱斯车身', engineName='劳斯莱斯发动机', information=劳斯莱斯@num6}
生产编号: 21685669
RollsRoyce{
    
    tirName='劳斯莱斯轮胎', bodyName='劳斯莱斯车身', engineName='劳斯莱斯发动机', information=劳斯莱斯@num7}
生产编号: 2133927002
RollsRoyce{
    
    tirName='劳斯莱斯轮胎', bodyName='劳斯莱斯车身', engineName='劳斯莱斯发动机', information=劳斯莱斯@num8}
生产编号: 1836019240
......
由于生产50台,数据过多暂列举一部分,生产编号均不同,information属性也不同

总结

突发奇想,嘻嘻,第一次使用这种举例的口吻写笔记,不知道效果好不好,实际上本章也是简单的介绍了原型模式的基本使用方式,以及浅拷贝与深拷贝深拷贝建议使用对象序列化实现(这篇文章有序列化实现深拷贝的方法)。

如果小伙伴们感觉写的还不错,麻烦随手给点个赞,嘿嘿,如果感觉写的不好也请私信我,我好改正,加油冲冲冲!

高工程师已经升为高高工程师了,他的路还要走多长呢?

猜你喜欢

转载自blog.csdn.net/weixin_43479947/article/details/107468497