如果我们正在做一个实时战略游戏。我们设计了一个武器,他制作只是当步兵,但他能够切换武器。第一个开关会变成弓箭手,第二个开关导通控股装甲盾牌,第三开关变成步兵……如何实现这一目标切换机构?我们开始思考,增加步兵在这个类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. ANDROID_MARS学习笔记_S02_010_Animation_动画效果

    一.流程 1.把要实现动画的一系列图片复制到res/drawable文件夹 2.在此文件新建一个xml文件用来组织图片 3.在mainactivity中用imageView.setBackground ...

  2. 第十章Composite设备

    10.1 Composite设备介绍 USB的Composite类是USB 复合设备类,一个USB设备具有多种设备功能,比如一个USB设备同时具有鼠标和键盘功能.单一的USB设备开发相对简单,但在很多 ...

  3. 6个常见的 PHP 安全性攻击

    了解常见的PHP应用程序安全威胁,可以确保你的PHP应用程序不受攻击.因此,本文将列出 6个常见的 PHP 安全性攻击,欢迎大家来阅读和学习. 1.SQL注入 SQL注入是一种恶意攻击,用户利用在表单 ...

  4. Android Touch事件传递机制

    1.基础知识 (1) 所有Touch事件都被封装成了MotionEvent对象,包括Touch的位置.时间.历史记录以及第几个手指(多指触摸)等. (2) 事件类型分为ACTION_DOWN, ACT ...

  5. GC回收建议

    1.最基本的建议就是尽早释放无用对象的引用.大多数程序员在使用临时变量的时候,都是让引用变量在退出活动域(scope)后,自动设置为 null.我们在使用这种方式时候,必须特别注意一些复杂的对象图,例 ...

  6. ActionBar官方教程(11)自定义ActionBar的样式(含重要的样式属性表及练习示例)

    Styling the Action Bar If you want to implement a visual design that represents your app's brand, th ...

  7. MySQL information_schema表查询导致内存暴涨

    case:下面的一条sql语句,导致mysql实例内存暴涨: select * from tables where table_name not in(select table_name from p ...

  8. WPF——传实体类

    User u; private void Button_Click_1(object sender, RoutedEventArgs e) //点击登陆按钮,弹出新窗体 { //先判断一下是不是正确的 ...

  9. 【HTML5】Canvas之globalCompositeOperation属性详解

    globalCompositeOperation即Canvas中的合成操作. 1.source-over 这是默认值,他表示绘制的图形将画在现有画布之上 <!DOCTYPE html> & ...

  10. C# 线程知识--使用ThreadPool执行异步操作

    C# 线程知识--使用ThreadPool执行异步操作 在应用程序中有许多复杂的任务,对于这些任务可能需要使用一个或多个工作线程或I/O线程来协作处理,比如:定时任务.数据库数据操作.web服务.文件 ...