Java从设计模式[本场比赛状态转换武器]状态分析(State)模式
如果我们正在做一个实时战略游戏。我们设计了一个武器,他制作只是当步兵,但他能够切换武器。第一个开关会变成弓箭手,第二个开关导通控股装甲盾牌,第三开关变成步兵……如何实现这一目标切换机构?我们开始思考,增加步兵在这个类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)模式的更多相关文章
- (转)Java经典设计模式(2):七大结构型模式(附实例和详解)
原文出处: 小宝鸽 总体来说设计模式分为三大类:创建型模式.结构型模式和行为型模式. 博主的上一篇文章已经提到过创建型模式,此外该文章还有设计模式概况和设计模式的六大原则.设计模式的六大原则是设计模式 ...
- Java描述设计模式(21):状态模式
本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景 1.场景描述 变色龙是爬行动物,是非常奇特的动物,它有适于树栖生活的种种特征和行为,身体也会随着环境的变化而变化出适应环境的颜色 ...
- (转)Java经典设计模式(1):五大创建型模式(附实例和详解)
原文出处: 小宝鸽 一.概况 总体来说设计模式分为三大类: (1)创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. (2)结构型模式,共七种:适配器模式.装饰器模式.代 ...
- Java设计模式(19)状态模式(State模式)
State的定义:不同的状态,不同的行为:或者说,每个状态有着相应的行为. 何时使用状态模式 State模式在实际使用中比较多,适合"状态的切换".因为我们经常会使用If else ...
- Java的设计模式
一.什么是设计模式: 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. ...
- java常用设计模式总览
一.java的设计模式大体上分为三大类: 创建型模式(5种):工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式. 结构型模式(7种):适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组 ...
- 【HeadFirst设计模式】10.状态模式
定义: 允许对象在内部状态改变时改变它 行为,对象看起来好像修改了它的类. OO原则: 封装变化 多用组合,少用继承 针对接口编程,不针对实现编程 为交互对象之间的松耦合设计而努力 类应该对扩展开放, ...
- Java设计模式学习记录-状态模式
前言 状态模式是一种行为模式,用于解决系统中复杂的对象状态转换以及各个状态下的封装等问题.状态模式是将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象的状态可以灵活多变.这样在客户端使 ...
- 《Java设计模式》之状态模式
状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式. 状态模式同意一个对象在其内部状态改变的时候改变其行为.这个对象看上去就像是改变了它 ...
随机推荐
- MFC浅析(7) CWnd类虚函数的调用时机、缺省实现
CWnd类虚函数的调用时机.缺省实现 FMD(http://www.fmdstudio.net) 1. Create 2. PreCreateWindow 3. PreSubclassWindow 4 ...
- PHP FTP上传文件
第一步:建立一个新的 FTP 连接. ftp_connect(host,port,timeout); host必需,规定要连接的 FTP 服务器,可以是域名或 IP 地址,后面不应以斜线结 ...
- 我的第一个Struts程序
1.程序结构 2.各种文件 LoginAction.java package com.tfj.action; public class LoginAction { private String use ...
- CentOS5.5 下编译安装 LAMP
大纲 1.安装gcc编译器 2.卸载rpm安装的http和mysql软件 3.编译安装php依赖包 4.安装apache软件 5.安装mysql软件 6.安装php软件 7.安装memcache ph ...
- Linux Kernel ‘oz_cdev_write()’函数本地缓冲区溢出漏洞
漏洞名称: Linux Kernel ‘oz_cdev_write()’函数本地缓冲区溢出漏洞 CNNVD编号: CNNVD-201311-060 发布时间: 2013-11-07 更新时间: 201 ...
- uc浏览器qq浏览器广告过滤
- VS2010如何调试IIS上的网站
通常,我们在Visual Studio里调试ASP.NET网站,都是加个断点,然后按F5,在VS自带的虚拟服务器下调试的.但有时候,VS自带的服务器弱爆了,无法满足一些特定情况的要求,我们必须把网站放 ...
- Linux文件类型与扩展名
Linux文件类型和Linux文件的文件名所代表的意义是两个不同的概念.我们通过一般应用程序而创建的比如file.txt.file.tar.gz ,这些文件虽然要用不同的程序来打开,但放在Linux文 ...
- 【JS】Beginner1:Making Stuff Happen
1.JS(JavaScript) is for interactivity 2.How does JS relate to HTML&CSS? script tag script elemen ...
- linux获取目录下文件
查看当前目录下的文件: find . -type f 查看当前目录下的文件夹: find . -type d 如果文件file1不为空: if [ -s file1 ];then echo ...