当前位置:文档之家› 建造者模式-游戏角色

建造者模式-游戏角色

完整解决方案Sunny公司开发人员决定使用建造者模式来实现游戏角色的创建,其基本结构如图8-3所示:图7-1 游戏角色创建结构图在图7-1中,ActorController充当指挥者,ActorBuilder充当抽象建造者,HeroBuilder、AngelBuilder和DevilBuilder充当具体建造者,Actor充当复杂产品。

完整代码如下所示://Actor角色类:复杂产品,考虑到代码的可读性,只列出部分成员属性,且成员属性的类型均为String,真实情况下,有些成员属性的类型需自定义class Actor{private String type; //角色类型private String sex; //性别private String face; //脸型private String costume; //服装private String hairstyle; //发型public void setType(String type) {this.type = type;}public void setSex(String sex) {this.sex = sex;}public void setFace(String face) {this.face = face;}public void setCostume(String costume) {this.costume = costume;}public void setHairstyle(String hairstyle) {this.hairstyle = hairstyle;}public String getType() {return (this.type);}public String getSex() {return (this.sex);}public String getFace() {return (this.face);}public String getCostume() {return (this.costume);}public String getHairstyle() {return (this.hairstyle);}}//角色建造器:抽象建造者abstract class ActorBuilder{protected Actor actor = new Actor();public abstract void buildType();public abstract void buildSex();public abstract void buildFace();public abstract void buildCostume();public abstract void buildHairstyle();//工厂方法,返回一个完整的游戏角色对象public Actor createActor(){return actor;}}//英雄角色建造器:具体建造者class HeroBuilder extends ActorBuilder{public void buildType(){actor.setType("英雄");}public void buildSex(){actor.setSex("男");}public void buildFace(){actor.setFace("英俊");}public void buildCostume(){actor.setCostume("盔甲");}public void buildHairstyle(){actor.setHairstyle("飘逸");}}//天使角色建造器:具体建造者class AngelBuilder extends ActorBuilder {public void buildType(){actor.setType("天使");}public void buildSex(){actor.setSex("女");}public void buildFace(){actor.setFace("漂亮");}public void buildCostume(){actor.setCostume("白裙");}public void buildHairstyle(){actor.setHairstyle("披肩长发");}}//恶魔角色建造器:具体建造者class DevilBuilder extends ActorBuilder {public void buildType(){actor.setType("恶魔");}public void buildSex(){actor.setSex("妖");}public void buildFace(){actor.setFace("丑陋");}public void buildCostume(){actor.setCostume("黑衣");}public void buildHairstyle(){actor.setHairstyle("光头");}}指挥者类ActorController定义了construct()方法,该方法拥有一个抽象建造者ActorBuilder类型的参数,在该方法内部实现了游戏角色对象的逐步构建,代码如下所示://游戏角色创建控制器:指挥者class ActorController{//逐步构建复杂产品对象public Actor construct(ActorBuilder ab){Actor actor;ab.buildType();ab.buildSex();ab.buildFace();ab.buildCostume();ab.buildHairstyle();actor=ab.createActor();return actor;}}为了提高系统的灵活性和可扩展性,我们将具体建造者类的类名存储在配置文件中,并通过工具类XMLUtil来读取配置文件并反射生成对象,XMLUtil类的代码如下所示:import javax.xml.parsers.*;import org.w3c.dom.*;import org.xml.sax.SAXException;import java.io.*;class XMLUtil{//该方法用于从XML配置文件中提取具体类类名,并返回一个实例对象public static Object getBean(){try{//创建文档对象DocumentBuilderFactory dFactory =DocumentBuilderFactory.newInstance();DocumentBuilder builder = dFactory.newDocumentBuilder();Document doc;doc = builder.parse(new File("config.xml"));//获取包含类名的文本节点NodeList nl = doc.getElementsByTagName("className");Node classNode=nl.item(0).getFirstChild();String cName=classNode.getNodeValue();//通过类名生成实例对象并将其返回Class c=Class.forName(cName);Object obj=c.newInstance();return obj;}catch(Exception e){e.printStackTrace();return null;}}}配置文件config.xml中存储了具体建造者类的类名,代码如下所示:<?xml version="1.0"?><config><className>AngelBuilder</className></config>编写如下客户端测试代码:class Client{public static void main(String args[]){ActorBuilder ab; //针对抽象建造者编程ab = (ActorBuilder)XMLUtil.getBean(); //反射生成具体建造者对象ActorController ac = new ActorController();Actor actor;actor = ac.construct(ab); //通过指挥者创建完整的建造者对象String type = actor.getType();System.out.println(type + "的外观:");System.out.println("性别:" + actor.getSex());System.out.println("面容:" + actor.getFace());System.out.println("服装:" + actor.getCostume());System.out.println("发型:" + actor.getHairstyle());}}编译并运行程序,输出结果如下:天使的外观:性别:女面容:漂亮服装:白裙发型:披肩长发在建造者模式中,客户端只需实例化指挥者类,指挥者类针对抽象建造者编程,客户端根据需要传入具体的建造者类型,指挥者将指导具体建造者一步一步构造一个完整的产品(逐步调用具体建造者的buildX()方法),相同的构造过程可以创建完全不同的产品。

在游戏角色实例中,如果需要更换角色,只需要修改配置文件,更换具体角色建造者类即可;如果需要增加新角色,可以增加一个新的具体角色建造者类作为抽象角色建造者的子类,再修改配置文件即可,原有代码无须修改,完全符合“开闭原则”。

相关主题