2023-04-01  阅读(37)
原文作者:LoveLion 原文地址:https://blog.csdn.net/lovelion/article/details/7426015

8.3 完整解决方案

Sunny公司开发人员决定使用建造者模式来实现游戏角色的创建,其基本结构如图8-3所示:

202304012051387371.png

图8-3 游戏角色创建结构图

在图8-3中,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中存储了具体建造者类的类名,代码如下所示:

AngelBuilder

编写如下客户端测试代码:

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()方法),相同的构造过程可以创建完全不同的产品。在游戏角色实例中,如果需要更换角色,只需要修改配置文件,更换具体角色建造者类即可;如果需要增加新角色,可以增加一个新的具体角色建造者类作为抽象角色建造者的子类,再修改配置文件即可,原有代码无须修改,完全符合“开闭原则”。


Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。

它的内容包括:

  • 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
  • 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
  • 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
  • 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
  • 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
  • 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
  • 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
  • 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw

目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:

想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询

同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。

阅读全文