从王者荣耀看设计模式(模板方法模式)
一:简介
玩家选择QQ或微信的登陆方式,点击登陆游戏,然后点击开始游戏,选择想要玩的英雄和召唤师技能,游戏开始(简易游戏流程模板)。
二:模板方法模式
定义一个操作中的算法的骨架,而将步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义算法的某些特定步骤。在模板方法模式中,我们需要准备一个抽象类,将部分逻辑以具体方法以及构造函数的形式实现,然后声明一些抽象方法来让子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。
模式动机
在现实生活中很多事情的完成过程都包含几个基础步骤。模板方法模式是基于继承的代码复用基本技术,在模板方法模式中,可以将相同的代码放在父类,而将不同的方法实现放在不同的子类中。在本实例中。进入游戏是由一系列的步骤组成的,在父类中定义一系列的步骤。其中选择登陆游戏方式和选择的英雄是不同的,所以可以放到子类中具体实现,
- 这其中涉及的设计原则有:
- 在模板方法模式中,我们需要准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来让子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。
- 控制子类扩展,子类必须遵守算法规则。
- 模板方法模式的优点:
- 模板方法模式通过把不变的行为搬移到超类,去除了子类中的重复代码。
- 子类实现算法的某些细节,有助于算法的扩展。
- 通过一个父类调用子类实现的操作,通过子类扩展增加新的行为,符合“开放-封闭原则”(软件实体应该是可扩展,而不可修改的。也就是说,对扩展是开放的,而对修改是封闭的)。
- 模板方法模式的缺点
- 每个不同的实现都需要定义一个子类,这会导致类的个数的增加,设计更加抽象。
三:结构图
四:设计类图
五:代码实现
Module类(定义简易游戏流程)
package com.game.Process;
/*
* 简易游戏流程抽象类
*/
public abstract class Module{
//模板方法,用来控制配置游戏的流程(游戏的流程是一样的-复用)
//申明为final,不希望子类复用这个方法,防止更改流程的执行顺序
public final void gameProcess(){
//第一步:选择登陆方式
this.loginMethod();
//第二步:登陆游戏
this.login();
//第三步:点击开始按钮
this.clickBeginBt();
//第四步:选择英雄
this.chooseHero();
//第五步:选择召唤师技能
this.chooseSkill();
//开始游戏
this.beginGame();
}
//定义结构里哪些方法是所有过程都是一样的可复用的,哪些是需要子类进行实现的
//第一步:登陆方式不一样(一个是QQ登陆,一个是微信登陆)
//所以申明为抽象方法,具体由子类实现
abstract void loginMethod();
//第二步:登陆游戏是一样的,直接实现
void login(){
System.out.println("登陆游戏");
}
//第三步:点击开始按钮是,直接实现
void clickBeginBt(){
System.out.println("点击开始按钮");
}
//第四步:玩家选择的英雄有差异,申明为抽象方法,具体由子类实现
abstract void chooseHero();
//第五步:选择召唤师技能不同,申明为抽象方法,具体由子类实现
abstract void chooseSkill();
//开始游戏
void beginGame(){
System.out.println("敌军还有5s到达战场,请做好准备!");
}
}
ModuleSon01类(Module子类,实现抽象方法)
package com.game.Process;
/*
*Module子类
*/
import com.game.Skill.impl.JiPao;
import com.game.Skill.impl.KuangBao;
import com.game.domain.HouYi;
import com.game.domain.LuBanQiHao;
public class ModuleSon01 extends Module {
void loginMethod() {
System.out.println("选择QQ登陆");
}
void chooseHero() {
System.out.println("选择出战的英雄是:【"+new HouYi().getHeroName()+"】");
}
void chooseSkill() {
HouYi hero=new HouYi();
System.out.print("选择的召唤师技能是:");
hero.setIskill(new JiPao());
hero.skill();
}
}
ModuleSon02类(实现Module抽象方法)
package com.game.Process;
/*
*Module子类
*/
import com.game.Skill.impl.KuangBao;
import com.game.domain.LuBanQiHao;
public class ModuleSon02 extends Module {
void loginMethod() {
System.out.println("选择微信登陆");
}
void chooseHero() {
System.out.println("选择出战的英雄是:【"+new LuBanQiHao().getHeroName()+"】");
}
void chooseSkill() {
LuBanQiHao hero=new LuBanQiHao();
System.out.print("选择的召唤师技能是:");
hero.setIskill(new KuangBao());
hero.skill();
}
}
Process测试类
package com.game.test;
/*
*游戏流程测试类
*/
import com.game.Process.ModuleSon01;
import com.game.Process.ModuleSon02;
public class ProcessTest {
public static void main(String[] args) {
System.out.println("=======Module01========");
ModuleSon01 process1=new ModuleSon01();
process1.gameProcess();
System.out.println("=======Module02========");
ModuleSon02 process2=new ModuleSon02();
process2.gameProcess();
}
}