如果我们正在做一个实时战略游戏。我们设计了一个武器,他制作只是当步兵,但他能够切换武器。第一个开关会变成弓箭手,第二个开关导通控股装甲盾牌,第三开关变成步兵……如何实现这一目标切换机构?我们开始思考,增加步兵在这个类switch声明。话,代码不利于扩展,不利于改动,这时我们就能够使用状态模式了。

状态模式同意一个对象在其内部状态改变时改变它的行为。对象看起来似乎改动了它的类。

在本例中,这个兵种有3个状态——步兵、弓箭手和装甲兵。我们将这3个状态都继承于同一个基类SoldierState,我们还须要定义一个兵种类来包括一个SoldierState对象,以便它是用来存储这些状态的,在本例中这个类的名字叫做KnightContext。

先看Java代码吧:

abstract class SoldierState {
public abstract void show();
protected void changeState(KnightContext knight, SoldierState soldierState){
knight.changeState(soldierState);
}
public abstract void transform(KnightContext knight);
} class KnightContext {
SoldierState state;
public KnightContext(){
state = SwordState.getState();
}
public void changeState(SoldierState state){
this.state = state;
state.show();
}
public void transform(){
state.transform(this);
}
} class SwordState extends SoldierState{
private static SoldierState state = new SwordState();
public static SoldierState getState(){
return state;
}
public void show() {
System.out.println("如今是步兵模式。");
}
public void transform(KnightContext knight) {
changeState(knight, BowState.getState());
}
} class BowState extends SoldierState{
private static SoldierState state = new BowState();
public static SoldierState getState(){
return state;
}
public void show() {
System.out.println("如今是弓箭模式。 ");
}
public void transform(KnightContext knight) {
changeState(knight, ShieldState.getState());
}
} class ShieldState extends SoldierState{
private static SoldierState state = new ShieldState();
public static SoldierState getState(){
return state;
}
public void show() {
System.out.println("如今是盾牌模式。");
}
public void transform(KnightContext knight) {
changeState(knight, SwordState.getState());
}
} public class State
{
public static void main(String[] args) {
KnightContext knight = new KnightContext();
knight.transform();
knight.transform();
knight.transform();
knight.transform();
knight.transform();
}

SwordState、BowState、ShieldState为此兵种的三个状态。KnightContext中有个SoldierState类型的成员state表示这个兵种的当前状态。

请注意。我们并不希望把怎样切换的过程写在KnightContext中(一般的想法可能是,在changeState中添加switch块,这样会使得KnightContext过于繁重),而是把怎样转换写在了SoldierState的transform方法中。这样就避免了在KnightContext中添加大量的切换状态的代码。假设须要新添加一个状态,仅仅须要改动和添加SoldierState的子类就可以。

对于每个状态。它都有一个单独的子类来表示。因此在状态多的情况下会出现非常多个子类,这也是状态模式的缺点。

程序执行的结果为:

如今是弓箭模式。

如今是盾牌模式。

如今是步兵模式。

今天是弓箭模式。

今天是屏蔽模式。

以上描述的状态模式,我希望你能帮忙。

Java从设计模式[本场比赛状态转换武器]状态分析(State)模式的更多相关文章

  1. (转)Java经典设计模式(2):七大结构型模式(附实例和详解)

    原文出处: 小宝鸽 总体来说设计模式分为三大类:创建型模式.结构型模式和行为型模式. 博主的上一篇文章已经提到过创建型模式,此外该文章还有设计模式概况和设计模式的六大原则.设计模式的六大原则是设计模式 ...

  2. Java描述设计模式(21):状态模式

    本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景 1.场景描述 变色龙是爬行动物,是非常奇特的动物,它有适于树栖生活的种种特征和行为,身体也会随着环境的变化而变化出适应环境的颜色 ...

  3. (转)Java经典设计模式(1):五大创建型模式(附实例和详解)

    原文出处: 小宝鸽 一.概况 总体来说设计模式分为三大类: (1)创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. (2)结构型模式,共七种:适配器模式.装饰器模式.代 ...

  4. Java设计模式(19)状态模式(State模式)

    State的定义:不同的状态,不同的行为:或者说,每个状态有着相应的行为. 何时使用状态模式 State模式在实际使用中比较多,适合"状态的切换".因为我们经常会使用If else ...

  5. Java的设计模式

    一.什么是设计模式: 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. ...

  6. java常用设计模式总览

    一.java的设计模式大体上分为三大类: 创建型模式(5种):工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式. 结构型模式(7种):适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组 ...

  7. 【HeadFirst设计模式】10.状态模式

    定义: 允许对象在内部状态改变时改变它 行为,对象看起来好像修改了它的类. OO原则: 封装变化 多用组合,少用继承 针对接口编程,不针对实现编程 为交互对象之间的松耦合设计而努力 类应该对扩展开放, ...

  8. Java设计模式学习记录-状态模式

    前言 状态模式是一种行为模式,用于解决系统中复杂的对象状态转换以及各个状态下的封装等问题.状态模式是将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象的状态可以灵活多变.这样在客户端使 ...

  9. 《Java设计模式》之状态模式

    状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式. 状态模式同意一个对象在其内部状态改变的时候改变其行为.这个对象看上去就像是改变了它 ...

随机推荐

  1. 环信_EaseUI 使用指南

    EaseUI 使用指南 简介 EaseUI 封装了 IM 功能常用的控件(如聊天会话.会话列表.联系人列表).旨在帮助开发者快速集成环信 SDK. 源码地址: EaseUI:https://githu ...

  2. 李洪强漫谈iOS开发[C语言-019]-断点调试

  3. INF文件

    百度百科:http://baike.baidu.com/view/637107.htm?fr=ala0_1_1 INF简介 INF是Device INFormation File的英文缩写,是Micr ...

  4. weblogic配置数据源出错

    Connection test failed. Listener refused the connection with the following error: ORA-12505, TNS:lis ...

  5. wcf 多个节点名出错

    无法加载协定为“ServiceReference1.xxxxxx”的终结点配置部分,因为找到了该协定的多个终结点配置.请按名称指示首选的终结点配置部分. 原因是config节点中多了endpoint相 ...

  6. JS正则表达式验证数字非常全

    <script type="text/javascript"> function validate(){ var reg = new RegExp("^[0- ...

  7. 【原创】LoadRunner Java Vuser开发环境配置指南

    1 编写目的 本文主要介绍Java运行环境的配置,同时通过编写HelloWorld程序,讲解在LoadRunner下如何开发简单的Java Vuser脚本.关于Java语言的深入学习,大家可以参考其他 ...

  8. 解决:javah 无法访问引用Android对象的问题

    无法访问android.view.View 是没有引入android.jar包 javah的参数中 有一个-bootclasspath参数 让他指向android.jar包 例如 javah -jni ...

  9. FZU Problem 2125 简单的等式

    思路:x绝对小于根号n,再由s(x,m)可以缩小范围.1e9十六进制大约算出每位和相加100左右.这种题直接判断范围再暴力. #include<stdio.h> #include<s ...

  10. HW3.16

    public class Solution { public static void main(String[] args) { int randomValue = (int)(Math.random ...