当创建给定类的实例的过程很昂贵或很复杂时,就使用原型模式。原型模式允许你通过复制现有的实例来创建新的实例。
示例—创建怪物
你设计的游戏中,需要怪兽的特征能够随着场景的变换而演化。例如在海底世界,创建海怪;在沙漠中,创建沙蝎怪物;在天空中,创建鸟人怪。由于创建怪物的过程比较复杂,需要在特定的类中统一复制创建,达到解耦的目的。
UML图表示
原型模式-创建怪物
代码演示
怪物抽象基类
package Prototype;
public abstract class Monster implements Cloneable {
private String scene;
private String name;
Monster(String scene, String name){
this.scene = scene;
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public String getScene() {
return scene;
}
public void setScene(String scene) {
this.scene = scene;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
海怪类
package Prototype;
public class SeaMonster extends Monster {
SeaMonster(String scene, String name) {
super(scene, name);
}
SeaMonster(String name) {
super("sea", name);
}
}
沙蝎类
package Prototype;
public class Scorpion extends Monster {
Scorpion(String scene, String name) {
super(scene, name);
}
Scorpion(String name){
super("sand",name);
}
}
鸟人类
package Prototype;
public class Birdy extends Monster {
Birdy(String scene, String name) {
super(scene, name);
}
Birdy(String name){
super("sky",name);
}
}
怪物注册类
package Prototype;
import java.util.HashMap;
public class MonsterRegistry {
private HashMap<String, Monster> monsterDB ;
MonsterRegistry(){
monsterDB = new HashMap();
monsterDB.put("sea", new SeaMonster("Sea Monster"));
monsterDB.put("sand",new Scorpion("Sand Scorpion"));
monsterDB.put("sky", new Birdy("Birdy"));
}
public Monster getMoster(String scene) throws CloneNotSupportedException {
Monster correctMonster = monsterDB.get(scene);
return (Monster)correctMonster.clone();
}
}
怪物生成类
package Prototype;
import java.util.Random;
public class MonsterMaker {
private MonsterRegistry registry;
private Random random = new Random(47);
MonsterMaker(){
registry = new MonsterRegistry();
}
void makeRandomMonster(String scene) throws CloneNotSupportedException {
int count = random.nextInt(10);
String name = "";
for (int i = 0; i < count ; i++){
Monster monster = registry.getMoster(scene);
name = monster.getName();
}
System.out.println("You will fight with " + count + " " + name + " in " + scene + ". ");
}
}
测试代码
package Prototype;
public class PrototypeDriver {
public static void main(String[] args) throws CloneNotSupportedException {
MonsterMaker monsterMake = new MonsterMaker();
System.out.println("You're in sea. ");
monsterMake.makeRandomMonster("sea");
System.out.println("You're in sky. ");
monsterMake.makeRandomMonster("sky");
System.out.println("You're in sand. ");
monsterMake.makeRandomMonster("sand");
}
}
测试结果
You're in sea.
You will fight with 8 Sea Monster in sea.
You're in sky.
You will fight with 5 Birdy in sky.
You're in sand.
You will fight with 3 Sand Scorpion in sand.