抄作业是变成功最快的路径,这些人善于利用周遭资源来完成自己的任务。

他们善于站在巨人的肩膀上摘果子,摘到的肯定是最红最大的果子。

当然了抄作业有各种类型,有的是你会做而不做,有的是你一学就会而不去学,有的是根本学不会。

其实很少有根本学不会的,所以基本上抄作业的人都是懒。但是懒是促进知识进步不可或缺的一个特征。

不能说他好也不能说他坏,他只是一种途径。

今天我们不谈哲学,我们只谈技术。

我们用一种设计模式来模拟抄作业——原型模式。

一、初始原型模式

上一篇我们讲了享元模式,这一篇讲的原型模式其实跟享元模式可以对照着学习,享元模式是创建了对象大家一起用,原型模式是大家找一样的对象。

比如你有一个对象,她温柔、知性、大方、孝顺,这时候你朋友来了,说我用用你女朋友,你肯定一个大嘴巴子呼上去了。但是你朋友说,你女朋友有没有姐姐、妹妹、堂姐、表妹啥的,跟她性格一样好的给我介绍介绍,这时候你肯定是内心沾沾自喜,还会尽力给你朋友找对象。

这就是享元莫斯和原型模式的区别,享元是公用,原型是复制(这里千万别成为杠精,我说的找对象不是真正意义上的复制,除非用对象细胞进行克隆人,这里的意思是在原有的对象基础上,找一个一样一样的对象,用来类比复制)

原型模式(Prototype Pattern)使用创建重复对象,同时又能保证性能。属于创建型模式。

一般是如果创建对象过程比较消耗资源或比较消耗时间的时候,我们会用这种设计模式。

我看网上很多说,Java实现的话需要继承Cloneable接口,我个人理解,可以但非必要。

二、图解原型模式

抄作业的人都过得怎么样了(原型模式)_原型模式

这里有两个对象中的模范:

小棋:善良、温柔、多才多艺

小紫:大方、知性、孝顺

当然了,找见两个这样的对象是很耗时间的,所以我们再想找的话,我们就可以说,我找一个像小琪一样的,这样就方便多了。

注意:找对象的时候 我们只复制身高、体重、爱好(这是个引用类型 注意了) 但是不复制名称(这里我是故意的)

三、码起来

Girl

package prototype;

import java.util.List;

/**
 * @author 木子的昼夜编程
 */
public  class Girl {
    // 名称
    String name;
    // 身高 cm
    int height;
    // 体重 kg
    int weight;
    // 爱好
    List<String> natures;
    // 克隆
    public  Girl cloneGirl(){
        // 没有任何初始化  你要是复制 我就给你个寂寞null
        // 本来想写成抽象的,但是后边需要new Gilr() 所以就没有抽象
        return  null;
    }

    @Override
    public String toString() {
        return "Girl{" +
                "name='" + name + '\'' +
                ", height=" + height +
                ", weight=" + weight +
                ", natures=" + natures +
                '}';
    }
}

GirlLikeXiaoQi

package prototype;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * @author 木子的昼夜编程
 */
public class GirlLikeXiaoQi extends Girl{

    // 构造函数中初始化小琪的所有属性
    public GirlLikeXiaoQi(){
        // 这里比较耗时 要花费好多年
        this.name = "小琪";
        this.height = 165;
        this.weight = 60;
        this.natures = Arrays.asList("善良","温柔","多才多艺");
    }
    @Override
    public Girl cloneGirl() {
        Girl girl = new Girl();
        // 名称不复制
        // 复制身高
        girl.height = this.height;
        // 复制体重
        girl.weight = this.weight;
        // 复制性格
        // 这样你就错了
        // girl.natures = this.natures;
        // 需要这样 也就是复制里边的元素
        girl.natures = new ArrayList<>(this.natures);
        return girl;
    }
}

GirlLikeXiaoZi

package prototype;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * @author 木子的昼夜编程
 */
public class GirlLikeXiaoZi extends Girl{

    // 构造函数中初始化小琪的所有属性
    public GirlLikeXiaoZi(){
        // 这里比较耗时 要花费好多年
        this.name = "小紫";
        this.height = 175;
        this.weight = 70;
        this.natures = Arrays.asList("大方","知性","孝顺");
    }
    @Override
    public Girl cloneGirl() {
        Girl girl = new Girl();
        // 名称不复制
        // 复制身高
        girl.height = this.height;
        // 复制体重
        girl.weight = this.weight;
        // 复制性格
        // 这样你就错了
        // girl.natures = this.natures;
        // 需要这样 也就是复制里边的元素
        girl.natures = new ArrayList<>(this.natures);
        return girl;
    }
}

GirlCache

package prototype;

import java.util.HashMap;

/**
 * @author 木子的昼夜编程
 */
public class GirlCache {
    // 存储所有已知对象
    static HashMap<String, Girl> girls;
    static {
        girls = new HashMap<>();
        girls.put("小琪", new GirlLikeXiaoQi());
        girls.put("小紫", new GirlLikeXiaoZi());
    }

    // 找像xxx一样的对象
    static Girl getGirl(String name){
        if (girls.containsKey(name)) {
            // 有 复制一个给你
            return girls.get(name).cloneGirl();
        } else {
            // 没有 滚
            return null;
        }
    }
}

Test

package prototype;


/**
 * @author 木子的昼夜编程
 */
public class Test {
    public static void main(String[] args) {
        // 看一眼小琪
        Girl xiaoqi = GirlCache.girls.get("小琪");
        System.out.println(xiaoqi);
        // 找一个像小琪一样对象
        Girl likeXiaoQi = GirlCache.getGirl("小琪");
        // 可以看到 除了名字 其他都一样
        System.out.println(likeXiaoQi);

        // 名字变成小琪表妹,性格加了一个幽默   做任何操作 都不影响小琪这个人
        likeXiaoQi.name = "小琪表妹";
        likeXiaoQi.natures.add("幽默");
        System.out.println(likeXiaoQi);
        // 看看小琪变了没  没变  小琪给你介绍了她表妹,你跟她表妹的事情,就不关小琪事儿了,
        // 总不能一直照着小琪来吧,那也太变态了
        System.out.println(xiaoqi);

        // 这时候小亮一看 这么方便的吗 我也要找 我找一个像伢伢的对象
        Girl likeyaya = GirlCache.girls.get("伢伢");
        // 可以看到 小亮对象是null 也就是没有伢伢这样的 就会给你返回个寂寞
        System.out.println("小亮对象:"+likeyaya);

        // 这时小明来了 说我要小紫一样的对象 小紫听着这么像他偶像邓紫棋呢
        Girl likexiaozi = GirlCache.getGirl("小紫");
        // 小明如愿以偿的找到了对象
        likexiaozi.name = "紫棋";
        likexiaozi.natures.add("超喜欢唱歌");
        System.out.println("小明对象:"+likexiaozi);



    }
}

输出结果:

抄作业的人都过得怎么样了(原型模式)_java_02

四、唠一唠

以后有人说你吃什么我吃什么,你买啥我买啥,你说干什么我就干什么

你可以回他一句:原型狗

他是以你为基础,复制成他的专属,与抄作业也差不了多少。