从王者荣耀看设计模式(建造者模式)

一.简介

为了玩王者荣耀的游戏体验感,不少玩家都会选择花钱购买自己常用英雄的皮肤。一方面,购买的皮肤通常要比原画更加"炫酷"。另一方面,购买的英雄皮肤常常伴随有特殊的回城特效与攻击技能特效。

二.模式动机

不管在生活中还是软件系统中,都存在一个包含多个组成部件的复杂对象,如汽车,它包括车轮、方向盘、发动机等各种部件。组成复杂对象的这些部件之间或许还会一定的约束,若某些属性没有赋值可能无法构成完整产品使用。如,电子邮件包含地址、收件人姓名、联系方式。创建产品的过程就是组合组件的过程。由于组合关系过程比较复杂,这些部件组合过程通常被"外部化"到一个称为建造者的对象里,建造者返还给客户端的是一个完整的产品对象。用户无须关心该对象属性以及它们的组合方式。在本实例中,玩家冲了钱的李白能建造有"凤求凰"的技能和回城特效。没有充钱的李白只能建造有系统默认技能特效和回城特效

三.建造者模式

建造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的创建过程可以创建不同的表示。建造者模式是一步一步创建一个复杂的对象,它允许对象只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。建造者模式又被称为生产者模式,属于创建型模式。

  • 建造者模式应用场景
    以下情况可以使用建造者模式
    ⑴. 需要生成的产品对象有着复杂的内部结构,这些产品对象通常包含多个成员属性
    ⑵. 需要生成的产品对象的属性相互依赖,需要指定其生成顺序
    ⑶. 对象的创建过程独立于创建该对象的类。在建造者模式中引入了指挥者类,将创建过程封装在指挥者类中,而不在建造者类中
    ⑷. 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品

  • 建造者模式涉及的设计原则有:
    ★对于扩展是开放的,对于修改是封闭的
    ★封装变化

  • 建造者模式通用类图:

  • 建造者模式涉及的角色有:
    Builder(抽象建造者)
    抽象建造者为创建一个产品Product对象的各个部件指定抽象接口,在该接口中一般声明两类方法,一类方法是buildPartX(),它们用于创建复杂对象的各个部件;另一类方法时getResult(),它们用于返回复杂对象。它既可以是抽象类,也可以是接口
    ConcreteBuilder(具体建造类)
    具体建造类实现了Builder接口,实现各个部件的构造和装配方法,定义明确它所创建的复杂对象,也可以提供一个方法返回创建好的复杂产品对象
    Product(产品角色)
    产品角色是被构建的复杂对象,包括多个组成部件,具体建造者创建该产品的内部表示并定义它的装配过程
    Director(指挥者)
    指挥者又称为导演类,它负责安排复杂对象的创建次序,指挥者与抽象建造者之间存在关联关系,可以在其construct方法中调用建造者对象的部件构造与装配方法,完成复杂对象的建造。客户端一般指需要与指挥类进行交互

建造者模式的优点:
⑴. 在建造者模式中,客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
⑵. 每一个具体建造者都相对独立,与其他的具体建造者无关,因此可以很方便地替换具体创建类或增加具体创建类,用户使用不同的具体创建者可得到不同的产品对象
⑶. 可以更加精细地控制产品的创建过程
⑷. 增加新的具体建造者无需修改原有类库的代码,指挥者类针对抽象建造者类编程,系统扩展方便,符合"开闭原则"
建造者模式的缺点:
⑴. 创建者模式所创建的产品一般具有较多的共同点,其组成部分相似。如果产品之间的差异很大,则不适合使用建造者模式,因此其适用范围受到一定的限制
⑵. 如果产品的内部变化复杂,可能会导致需要定义更多具体建造者类来实现这种变化,导致系统变得很庞大

四.结构图

五.设计类图

六.代码实现

创建产品类(Effection类)

package com.practice.Director;
/** 产品类Effection(英雄效果类)* @param backEffection 英雄回城效果* @param skillEffection 英雄技能效果*/
public class Effection {//回城和技能都是组成整个游戏效果的部件private String backEffection;private String skillEffection;public String getBackEffection() {return backEffection;}public void setBackEffection(String backEffection) {this.backEffection = backEffection;}public String getSkillEffection() {return skillEffection;}public void setSkillEffection(String skillEffection) {this.skillEffection = skillEffection;}
}

创建抽象建造者类(HeroEffectionBuilder)

package com.practice.Director;
/** 抽象建造者类HeroEffectionBuilder(英雄效果建造者类)*/
public abstract class HeroEffectionBuilder {protected Effection effection = new Effection();public abstract void buildBackEffection();public abstract void buildSkillEffection();public Effection getEffection() {return effection;}
}

创建具体建造者类(LiBaiEffectionBuilderA)

package com.practice.Director;
/** 具体创建者类LiBaiEffectionBuilderA*/
public class LiBaiEffectionBuilderA extends HeroEffectionBuilder {public void buildBackEffection() {effection.setBackEffection("李白系统默认回城特效:熊猫回城");}public void buildSkillEffection() {effection.setSkillEffection("李白默认二技能神来之笔效果");}
}

创建具体建造者类(LiBaiEffectionBuilderB)

package com.practice.Director;
/** 具体创建者类LiBaiEffectionBuilderB*/
public class LiBaiEffectionBuilderB extends HeroEffectionBuilder {public void buildBackEffection() {effection.setBackEffection("李白皮肤特效\"凤求凰\""+"回城特效");}public void buildSkillEffection() {effection.setSkillEffection("李白皮肤特效\"凤求凰\""+"二技能神来之笔效果");}
}

创建指挥类(GameManager类)

package com.practice.Builder;import com.practice.Director.Effection;
import com.practice.Director.HeroEffectionBuilder;/** 指挥者类GameManager*/
public class GameManager {private HeroEffectionBuilder heb;public void setHeroEffectionBuilder(HeroEffectionBuilder _heb) {this.heb = _heb;}public Effection construct() {heb.buildBackEffection();heb.buildSkillEffection();return heb.getEffection();}
}

创建XML配置文件(Config.xml)

<?xml version="1.0" encoding="UTF-8"?>
<config><isPayMoney>false</isPayMoney>
</config>

创建工具类读取config.xml(XNLUtilEffection类)

package com.practice.Client;import java.io.File;
import javax.xml.parsers.*;
import org.w3c.dom.*;public class XMLUtilEffection {//该方法用于从XML配置文件中提取具体类类名。并返回一个实例对象public static Boolean getIsPayMoney() {try {//创建文档对象DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();DocumentBuilder builder = dFactory.newDocumentBuilder();Document doc;doc = builder.parse(new File("src\\com\\practice\\Client\\config.xml"));//获取包含类名的文本节点NodeList nl = doc.getElementsByTagName("isPayMoney");Node classNode = nl.item(0).getFirstChild();String Ispay = classNode.getNodeValue();boolean IspayMoney = Boolean.parseBoolean(Ispay);return IspayMoney;}catch(Exception e) {e.printStackTrace();return null;}}
}

创建客户端测试(Client类)

package com.practice.Client;import com.practice.Builder.GameManager;
import com.practice.Director.Effection;
import com.practice.Director.HeroEffectionBuilder;
import com.practice.Director.LiBaiEffectionBuilderA;
import com.practice.Director.LiBaiEffectionBuilderB;public class Client {public static void main(String [] args) {HeroEffectionBuilder heb = null;Boolean isPayMoney = XMLUtilEffection.getIsPayMoney();if(isPayMoney) {heb = new LiBaiEffectionBuilderB();}else {heb = new LiBaiEffectionBuilderA(); }GameManager gm = new GameManager();gm.setHeroEffectionBuilder(heb);Effection effection = gm.construct();System.out.println("英雄特效:");System.out.println(effection.getBackEffection());System.out.println(effection.getSkillEffection());}
}

运行结果:

修改配置文件XML:

<?xml version="1.0" encoding="UTF-8"?>
<config><isPayMoney>true</isPayMoney>
</config>

运行结果:

建造者模式与抽象工厂模式比较
■ 与抽象工厂模式相比,建造者模式返回一个组装好的完整产品,而抽象工厂模式返回一系列相关的产品,这些产品位于不同的产品等级结构,构成了一个产品族。
■ 在抽象工厂模式中,客户端实例化工厂类,然后调用工厂方法获取所需产品对象,而在建造者模式中,客户端可以不直接调用建造者的相关方法,而是通过指挥类来指导如何生成对象
如果将抽象工厂模式看成汽车配件生产工厂,生产一个产品族的产品,那么建造者模式就是一个汽车组装工厂,通过对部件的组装可以返回一辆完整的汽车

七.源代码下载

从王者荣耀看设计模式(建造者模式)

从王者荣耀看设计模式(十五.建造者模式)相关推荐

  1. 从王者荣耀看设计模式(五.组合模式)

    从王者荣耀看设计模式(组合模式) 一.简介 在王者荣耀这款游戏中,我们可以在商店中购买英雄.英雄由法师.射手.打野等职业组合而成,其中各个职业由中国元素的英雄和外国元素的英雄组成,玩家可根据需要挑选并 ...

  2. 从王者荣耀看设计模式(六.状态模式)

    从王者荣耀看设计模式(状态模式) 一.简介 英雄项羽在敌方英雄的攻击下存在3种不同的状态. 1.在健康生命值下--普通状态,在每次被攻击时,当前生命值=剩余生命值-敌方英雄伤害值 2.在生命值低于某一 ...

  3. 从王者荣耀看设计模式(一.策略模式)

    从王者荣耀看设计模式(策略模式) 一:简介 游戏开始前,玩家需要选择英雄,再根据所选择的阵容自由选择召唤师技能,游戏开始,玩家可以控制英雄进行普通攻击和使用召唤师技能攻击 二:策略模式 策略模式将可变 ...

  4. 从王者荣耀看设计模式(虚拟代理模式)

    从王者荣耀看设计模式(虚拟代理模式) 一.简介 王者荣耀游戏设置了很多种游戏模式,比如:王者模拟战.无限乱斗.梦境大乱斗.火焰山大战等.当从王者荣耀的主界面进入各类模式的界面时,由于网络原因,会存在一 ...

  5. 从王者荣耀看设计模式(十七.桥接模式)

    从王者荣耀看设计模式(桥接模式) 一.简介 王者荣耀是一款RGB游戏,玩家操控自己选择的英雄进行竞赛.在游戏正式开始前,玩家在挑选想要操作的英雄的同时,也会挑选适合该英雄的召唤师技能.召唤师技能是通用 ...

  6. 从王者荣耀看设计模式(保护代理模式)

    从王者荣耀看设计模式(保护模式) 一.简介 打开王者荣耀,点击右上角头像标志可进入我的信息主页.在我的个人主页中,我可以可设置玩家的游戏昵称,性别,常用英雄.除此之外,我还可以查看自己得到别人点赞的次 ...

  7. 从王者荣耀看设计模式(远程代理模式)

    从王者荣耀看设计模式(远程代理模式) 一.简介 每位王者荣耀玩家都有一个属于自己的游戏账号.为了提升游戏等级或者增加游戏体验感,会存在多个游戏玩家同时共享一个游戏账号的情况.当一位玩家使用账号正在游戏 ...

  8. 从王者荣耀看设计模式(四.简单工厂模式)

    从王者荣耀看设计模式(简单工厂模式) 一.简介 游戏开始前,玩家可从英雄池自由挑选将要出战的英雄 二.简单工厂模式 简单工厂模式(Simple Factory Pattern)属于类的创新型模式,又叫 ...

  9. 从王者荣耀看设计模式(七.装饰者模式)

    ##从王者荣耀看设计模式(装饰者模式) 一.简介 王者荣耀中,角色的"伤害值"和"生命值"是很重要的概念.为了保证游戏的胜利,玩家会通过在游戏开始前配置合适的游 ...

最新文章

  1. 手持发光棒的结构解析
  2. 【Centos 7】【Docker】 安装 kafka
  3. mysql-mmm高可用架构
  4. 表白和被表白时遇到的骚操作,最后一个天秀!| 今日最佳
  5. 直接在 CSS 中引用 FONTAWESOME 图标(附码表)
  6. oracle 如何修改字符集 update prop,ORACLE 修改字符集
  7. oracle x kglob,x$kglob x$kgllk x$kglpn
  8. MAC下的环境变量配置
  9. PayPal支付时出现“该商家目前无法接受PayPal付款。请稍后重试,或返回商家页面并选择其他付款方式。”
  10. 驻点、极值点与拐点(判断极值点与拐点的方法)
  11. Oracle等待事件之buffer busy waits
  12. 数据链路层之以太网、MAC、MTU详解
  13. postgres关键字、常量和数据类型
  14. RN-Flex Box---基础
  15. Android O 版本(Android 8.0) 存储空间不足时提醒
  16. java 制作自定义控件_C#下自定义控件的制作 一
  17. 和风天气ouc——about页面
  18. PBR来龙去脉十一:IBL继续积分部分
  19. 深度学习入门笔记(六):浅层神经网络
  20. GOP/ 码流 /码率 / 比特率 / 帧速率 / 分辨率【转】

热门文章

  1. odoo 关于many2many 和one2many
  2. C#工程 引用了库,但是找不到命名空间
  3. win10系统ie直接跳转edge还原方法
  4. 超级英雄榜 | 四届量子计算黑客松大赛英雄榜公布,50位开发者成功上榜!
  5. 文字超出部分变成省略号的三种方式
  6. 2017年智能家居市场分析预测 存5大悬念
  7. [树状数组]飘雪圣域
  8. 折叠手机和反对创新的战争
  9. 第十代酷睿 I7 IPSEC加密转发性能测试报告
  10. windows server 2008防火墙阻止局域网不能访问解决方案