早年一直有新闻报道,XXX拖欠农民工工资的情况,甚至没有和员工签订合同的。这种做法当然不好,但现实也是挺残酷的,上门为了利润,就这么做,能省就省,遇到什么工伤之类的都不用赔,因为没有合同,你怎么说工伤呢?
这和大公司开一家小公司,去做特定的项目类似,规避风险。
假设我们有一份 重要的合同,需要一式两份保存,每人个一份。
这时候我们要快速的备份一份,因为内容完全一样,这时候就可以用原型模型
代码实现
我们写一个合同类,里面有合同的日期,合同的具体内容,签名的人的列表。
就像下面这个这样。
public class Contract implements Cloneable{
public String context;
public List<String> sign;
public Date date;
@Override
public Contract clone(){
try {
Contract newContract= (Contract) super.clone();
newContract.context=this.context;
newContract.date=this.date;
newContract.sign=this.sign;
return newContract;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
}
我们的合同实现了Cloneable
接口,所以我们可以快速的copy一份
具体如下
public class client {
public static void main(String[] args) {
Contract contract=new Contract();
contract.context="this is contract text";
contract.date=new Date(System.currentTimeMillis());
List<String> signs=new ArrayList<>();
signs.add("jack");
signs.add("tom");
contract.sign=signs;
Contract mContract=contract.clone();
}
}
好了,我们的原型模型实际说的就是这样,快速的复制一份。
不过有点需要提示的,就是这是一种浅拷贝
。
并没有做到完全的独立的两份。
下面的例子就可以告诉你结果。
我们简单的修改前面的例子,加多一点修改
public static void main(String[] args) {
Contract originalContract=new Contract();
originalContract.context="this is contract text";
originalContract.date=new Date(System.currentTimeMillis());
List<String> signs=new ArrayList<>();
signs.add("jack");
signs.add("tom");
originalContract.sign=signs;
Contract mCopyContract=originalContract.clone();
mCopyContract.context="change the context";
mCopyContract.sign.add("rose");
System.out.println("oriContext=" + originalContract.context + ", copyContext=" + mCopyContract.context);
System.out.println("oriSign ="+ originalContract.sign +" copySign="+mCopyContract.sign);
}
我们拷贝后,修改我们的合同的内容,同时在拷贝版的合同加多rose
的签名。理论上来说,我们的合同时一式两份,应该互不相干的。对原本的合同也不应该有任何影响,带着这样的判断,我们看下打印的内容。
oriContext=this is contract text, copyContext=change the context
oriSign =[jack, tom, rose] copySign=[jack, tom, rose]
我们看到我们的合同的内容是两份不一样,不过我们的签名!居然两份都有了,这不科学啊!
如果你曾经学过C/C++
,这个就好结实,对于Sign
的复制,他们就是给了指针,单纯的引用,并没有给我们重现开辟一个地方来保存!
所以我们需要修改原来的复制的地方!
改成深拷贝
的。
public ArrayList<String> sign;
@Override
public Contract clone(){
try {
Contract newContract= (Contract) super.clone();
newContract.context=this.context;
newContract.date=this.date;
newContract.sign= (ArrayList<String>) this.sign.clone();//注意这里。
return newContract;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
我们修改了我们的sign
是一个具体的ArrayList
类型,同时复制的时候加多clone()
调用。
现在我们就可以安心快速的复制一个内容了,很好。
后记
这个原型模型应该是这些模型中最简单的吧,
因为他实际可以简单说的成就是一样事情,拷贝。
拷贝我们原来的东西,而且我们的java语言已经提供了这个特性接口。
不过有一些需要提下的,就是这个原型模型比较适合构造成本比较高的,或者构造较为麻烦的情况,特别是一个循环里面生成大量的对象情况,因为他背后是在内存中二进制流的拷贝,所以他的构造函数是
不会被执行的,这个需要特别注意!!
对于简单的,还是使用new一个好。
写了这么多篇设计模式的内容,回去重新看了写的前面的内容,
整体写得内容的表述还是很一般一般的,但可以看到有逐渐的改善!
这是一个挺好的事,虽然我写的不是很通俗易懂,但继续写的过程,不断有一些改善,这就很好了。同时也回去修改一些错误,感觉这就比没写文章时候更好了,这就值了。