写点什么

设计模式的艺术 第二十三章状态设计模式练习(设计一款纸牌游戏软件,该游戏中用户角色具有入门级、熟练级、高手级和骨灰级 4 种等级。角色等级与积分对应,胜利增加积分,失败扣除积分。入门级有最基本的游戏功能,熟练级增加胜利积分加倍功能,高手级再增加换牌功能)

作者:代廉洁
  • 2022 年 8 月 31 日
    浙江
  • 本文字数:3229 字

    阅读完需:约 11 分钟

Sunny 公司欲开发一款纸牌游戏软件,在该游戏软件中用户角色具有入门级(Primary)、熟练级(Secondary)、高手级(Professional)和骨灰级(Final)4 种等级。角色的等级与其积分相对应,游戏胜利将增加积分,失败则扣除积分。入门级具有最基本的游戏功能 play(),熟练级增加了游戏胜利积分加倍功能 doubleScore(),高手级在熟练级的基础上再增加换牌功能 changeCards(),骨灰级在高手级基础上再增加偷看他人的牌的功能 peekCards()。试使用状态模式来设计该系统。


一、类结构图



抽象状态类:设计为名称为 PlayerState 的抽象类,持有一个环境类对象的引用,用以检查并实现状态之间的转换,抽象状态类 PlayerState 包含抽象业务方法 play()、抽象业务方法 win()、具体业务方法 lose()、检查状态并转换状态的抽象方法 checkState();

环境类:设计为具体类 Player,持有一个抽象状态类的引用,包括具体业务方法 play()、具体业务方法 win()、具体业务方法 lose();

具体状态类:设计为抽象状态类 PlayerState 的子类,包含具体方法 play()、检查状态并转换转换的具体方法 checkState(),包括具体状态类 PrimaryState、具体状态类 SecondaryState、具体状态类 ProfessionalState、具体状态类 FinalState。

二、典型实现代码


抽象玩家状态类:抽象状态类
// 抽象玩家状态类:抽象状态类public abstract class PlayState {    protected Player player;    public abstract void play();    public abstract void win();    public void lose() {        System.out.println("游戏失败,扣除积分");        Integer score = player.getScore() - 10;        this.player.setScore(score);        checkState();    }    public abstract void checkState();}
复制代码


具体玩家类:环境类
// 具体玩家类:环境类public class Player {    private String name;    private Integer score;    private PlayState state;
public Player(String name) { this.name = name; this.score = 0; this.state = new PrimaryState(this); System.out.println("新建帐户,积分为:" + this.score); }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Integer getScore() { return score; }
public void setScore(Integer score) { this.score = score; }
public PlayState getState() { return state; }
public void setState(PlayState state) { this.state = state; }
public void play() { this.state.play(); }
public void win() { this.state.win(); System.out.println("积分为:" + this.score); System.out.println("状态为:" + this.state.getClass().getSimpleName()); }
public void lose() { this.state.lose(); System.out.println("积分为:" + this.score); System.out.println("状态为:" + this.state.getClass().getSimpleName()); }}
复制代码


入门级状态类:具体状态类
// 入门级状态类:具体状态类public class PrimaryState extends PlayState{    public PrimaryState(Player player) {        this.player = player;    }
public PrimaryState(PlayState state) { this.player = state.player; }
@Override public void play() { System.out.println("开始游戏"); }
@Override public void win() { System.out.println("游戏胜利,获取积分"); int score = this.player.getScore() + 10; this.player.setScore(score); checkState(); }
@Override public void checkState() { if (this.player.getScore() >= 100 && this.player.getScore() < 500) { this.player.setState(new SecondaryState(this)); } if (this.player.getScore() >= 500 && this.player.getScore() < 1000) { this.player.setState(new ProfessionalState(this)); } if (this.player.getScore() >= 1000) { this.player.setState(new FinalState(this)); } }}
复制代码


熟练级状态类:具体状态类
// 熟练级状态类:具体状态类public class SecondaryState extends PrimaryState{    public SecondaryState(PlayState state) {        super(state);    }
@Override public void win() { System.out.println("游戏胜利,获取积分"); doubleScore(); checkState(); }
public void doubleScore() { int score = this.player.getScore() + 10*2; this.player.setScore(score); }
@Override public void checkState() { if (this.player.getScore() >= 500 && this.player.getScore() < 1000) { this.player.setState(new ProfessionalState(this)); } if (this.player.getScore() < 100) { this.player.setState(new PrimaryState(this)); } if (this.player.getScore() >= 1000) { this.player.setState(new FinalState(this)); } }}
复制代码


高手级状态类:具体状态类
// 高手级状态类:具体状态类public class ProfessionalState extends SecondaryState{    public ProfessionalState(PlayState state) {        super(state);    }
@Override public void play() { super.play(); changeCards(); }
public void changeCards() { System.out.println("启用换牌功能"); }
@Override public void checkState() { if (this.player.getScore() >= 1000) { this.player.setState(new FinalState(this)); } if (this.player.getScore() >= 100 && this.player.getScore() < 500) { this.player.setState(new SecondaryState(this)); } if (this.player.getScore() < 100) { this.player.setState(new PrimaryState(this)); } }}
复制代码


骨灰级状态类:具体状态类
// 骨灰级状态类:具体状态类public class FinalState extends ProfessionalState{    public FinalState(PlayState state) {        super(state);    }
@Override public void play() { super.play(); peekCards(); }
public void peekCards() { System.out.println("启用偷看别人牌的功能"); }
@Override public void checkState() { if (this.player.getScore() >= 500 && this.player.getScore() < 1000) { this.player.setState(new ProfessionalState(this)); } if (this.player.getScore() >= 100 && this.player.getScore() < 500) { this.player.setState(new SecondaryState(this)); } if (this.player.getScore() < 100) { this.player.setState(new PrimaryState(this)); } }}
复制代码


客户端代码:
public class Client {    public static void main(String[] args) {        Player player = new Player("段誉");        player.play();        player.win();        player.lose();    }}
复制代码


编译并运行程序,输出如下结果:
新建帐户,积分为:0开始游戏游戏胜利,获取积分积分为:10状态为:PrimaryState游戏失败,扣除积分积分为:0状态为:PrimaryState
复制代码


发布于: 12 小时前阅读数: 15
用户头像

代廉洁

关注

还未添加个人签名 2019.10.15 加入

还未添加个人简介

评论

发布
暂无评论
设计模式的艺术 第二十三章状态设计模式练习(设计一款纸牌游戏软件,该游戏中用户角色具有入门级、熟练级、高手级和骨灰级4种等级。角色等级与积分对应,胜利增加积分,失败扣除积分。入门级有最基本的游戏功能,熟练级增加胜利积分加倍功能,高手级再增加换牌功能)_设计模式的艺术_代廉洁_InfoQ写作社区