原型模式就是实现了cloneable接口的类作为原型以clone代替new对象。clone在底层上是以二进制码进行复制所以效率要比直接生成一个对象效率要高。该模式经常与其他模式混用。
有个动漫叫《某科学的超电磁炮》,其中的主人公炮姐是学院里为数不多的等级水平为level5的超能力者。会抛射硬币和发电等技能。因为某项实验被克隆了很多份,克隆产品虽然会炮姐的招式,但是都没有炮姐的level值高。那么这个逻辑用代码怎么写?
先看看我们超能力者类,用到了模板方法。
public abstract class SuperMan implements Cloneable {
//统计克隆个数
private static int number = 0;
//为克隆对象给予编号
protected int id;
//超能力者的名字
private String name = null;
//超能力者的等级
protected int level;
//两种攻击方式
public abstract void attack1();
public abstract void attack2();
protected int getId() {return id; }
public void setNumber() { id = ++number; }
public void setLevel() {//只有level才有资格被克隆,克隆对象的等级没有原版高
this.level = (int) (Math.random() * 4 + 1);
}
public void show() {
System.out.println("等级为" + level);
attack1();
attack2();
}
@Override//实现了cloneable接口
protected Object clone() throws CloneNotSupportedException {
SuperMan newMan = (SuperMan) super.clone();
newMan.setNumber();
newMan.setLevel();
return newMan;
}
}
炮姐继承了SuperMan这个类,因为炮姐只有一个。所以又用到了单例模式。
public class PaoSister extends SuperMan {
private String name;
private static PaoSister paoSister = new PaoSister();
public PaoSister(){ name = "炮姐r";level = 5; }
public void attack1() {
System.out.println(name+getId()+"发射硬币");
}
public void attack2() {
System.out.println(name+getId()+"暴力发电");
}
public static PaoSister getPaoSister(){
return paoSister;
}
}
最后看看场景,第一次研究嘛先生成两个看看。
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
PaoSister paoSister = PaoSister.getPaoSister();
paoSister.show();
PaoSister p1 = (PaoSister) paoSister.clone();
PaoSister p2 = (PaoSister) paoSister.clone();
p1.show();
p2.show();
}
}
等级为5
炮姐0发射硬币
炮姐0暴力发电
等级为3
炮姐1发射硬币
炮姐1暴力发电
等级为3
炮姐2发射硬币
炮姐2暴力发电
不错不错实验完毕!一方通行马上就可以大杀特杀了~