在JavaScript中,通常使用prototype关键字实现面向对象。但在设计模式中,简单点说就是复制。其实入门时学习的那个什么排序,用一个temp变量复制另一个值用于对换也是一种相当迷你的原型模式。
原型模式 Prototype
问题:
Application “hard wires” the class of object to create in each “new” expression.
意图:
- Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.
- Co-opt one instance of a class for use as a breeder of all future instances.
- The new operator considered harmful.
例:若是一个对象,有两个用途,但其中一个会改变对象的内部属性,但对象本身也没有自动还原方法,可以自己做一个类似clone的方法出来,产生一个一模一样的对象分开用
代码1:定义接口(非必须)
public interface ProtoType {
public ProtoType clone();
}
代码二:定义数据,实现原型接口
package com.xdnote.DesignPattern.creational.prototype;
public class Data implements ProtoType {
private String key;
private String value;
public Data(String key, String value) {
this.key = key;
this.value = value;
}
public ProtoType clone(){
return new Data(this.key,this.value);
}
public String getKey() {
return key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
代码三:客户端使用
public static void main(String[] args){
Data d1 = new Data("a","b");
Data d2 = (Data) d1.clone();
d2.setValue("c");
System.out.println("d1 key:"+d1.getKey()+" value:"+d1.getValue());
System.out.println("d2 key:"+d2.getKey()+" value:"+d2.getValue());
//如果没有这个模式,就是对象引了
Data d3 = new Data("a","d");
Data d4 = d3;
d4.setValue("e");
System.out.println("d3 key:"+d3.getKey()+" value:"+d3.getValue());
System.out.println("d4 key:"+d4.getKey()+" value:"+d4.getValue());
}
小结
原型模式 Prototype
由于底层基本上去是通过指针传递对象的,要使用同样的两个对象时,不能用 tmp = obj ,实际上还是一个。
- 使用频率:
中
通常我调用setValue之类的方法时,不会考虑前后给set前后两个不同的函数去计算。但我们经常使用复制数组,排序的一些小技巧,从思想上也是一致的
- 利弊影响:
极低
利:一般使用原型就这么个原因,即使不写注释,另人也能看得懂
弊:面向对象有点恶心,一个clone也要单独写的。
- 小评:
如果你发现你的项目里面需要写大量的原型模式,那么建议想想有没其它更好的方法可以解决。