抄作业是变成功最快的路径,这些人善于利用周遭资源来完成自己的任务。
他们善于站在巨人的肩膀上摘果子,摘到的肯定是最红最大的果子。
当然了抄作业有各种类型,有的是你会做而不做,有的是你一学就会而不去学,有的是根本学不会。
其实很少有根本学不会的,所以基本上抄作业的人都是懒。但是懒是促进知识进步不可或缺的一个特征。
不能说他好也不能说他坏,他只是一种途径。
今天我们不谈哲学,我们只谈技术。
我们用一种设计模式来模拟抄作业——原型模式。
一、初始原型模式
上一篇我们讲了享元模式,这一篇讲的原型模式其实跟享元模式可以对照着学习,享元模式是创建了对象大家一起用,原型模式是大家找一样的对象。
比如你有一个对象,她温柔、知性、大方、孝顺,这时候你朋友来了,说我用用你女朋友,你肯定一个大嘴巴子呼上去了。但是你朋友说,你女朋友有没有姐姐、妹妹、堂姐、表妹啥的,跟她性格一样好的给我介绍介绍,这时候你肯定是内心沾沾自喜,还会尽力给你朋友找对象。
这就是享元莫斯和原型模式的区别,享元是公用,原型是复制(这里千万别成为杠精,我说的找对象不是真正意义上的复制,除非用对象细胞进行克隆人,这里的意思是在原有的对象基础上,找一个一样一样的对象,用来类比复制)
原型模式(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);
}
}
输出结果:
四、唠一唠
以后有人说你吃什么我吃什么,你买啥我买啥,你说干什么我就干什么
你可以回他一句:原型狗
他是以你为基础,复制成他的专属,与抄作业也差不了多少。