从魔兽世界看状态模式
程序员文章站
2022-04-22 16:42:42
...
有学过物理课的同学都知道物理课本里面有固态,液态,气态,用来描述物体的形态。但在面向对象的软件世界中,状态可以用来描述各种各样的对象。比如你想在淘宝买一个商品,此时商品肯定是在售状态,如果这个商品已经售完;如果这个商品已经被买家购买一空,那么商品变成了售空状态;如果中途这个商品被发现质量有问题,于是变成了下架状态。当然真正的商品状态肯定不止这些,这里只是举了些例。
网络上有把状态模式说成是策略模式的孪生兄弟。从实现角度来讲他们确实非常类似。但它们的应用场景却略有不同。
我想接着上一节策略模式的例子,继续用魔兽世界这款游戏来讲解状态模式和策略模式的区别。
组队模式已经在策略模式篇中有详细介绍。
游戏设计者很聪明的选择了队长选定难度的方式来决定进入哪个地下城。把选择权交给玩家是典型的策略模式的应用场景。
让我们来给设计者们增加一些难度。假设说游戏里并没有队长选定难度的方法,而是根据玩家队伍里的人数来决定进入哪个地下城。游戏设计者们该如何设计这种方式呢?下面的图说明了这种方式的不同。可以明显地看到这两种方式的区别,此种方式选择权已经不在队长手上。
那么,如果说还需要增加难度,则会如下图所示。
如果把人数的变化看成队伍状态的一种变化,合格的设计者会提前定义出针对每种状态的算法。
比如: 队伍人数10人或以下 状态一
队伍人数10人以上至25人 状态二
队伍人数25人以上至40人 状态三
针对每种状态的算法,如下图所示。
这样做的好处是如果以后要加入60人(状态四)或者80人(状态五)的地下城,程序的结构会非常清晰。
上面的结构其实就是状态模式的典型应用,当然到这里还没有结束。可以从上图看到状态模式和策略模式在实现上何其类似。
我想用伪代码的形式来说明状态模式的应用,分为不使用模式和使用模式:
1、应用状态模式之前,看到的应该是这样的逻辑:
//如果队伍人数在10人或以下
//初始化10人地下城
//如果队伍人数在10人以上至25人
//初始化25人地下城
.....
2、应用状态模式之后,看到的应该是这样的逻辑:
//根据玩家人数初始化对应的地下城(统一入口)
不使用模式的做法在算法不是非常多的情况下非常适合。套用程序员的白话讲就是把代码逻辑写死。
但第二种更灵活,并且很方便扩展。因为人数是动态的,状态模式带来的好处是明显的,就是在程序运行时动态地替换算法。而不用把代码写死。
以上的表述和策略模式基本相同,从一个侧面也证明了状态模式和策略模式的相似之处。
关于如何用代码实现状态模式,网上有很多文章,使了用各种语言,不管是C++,C#,Java还是动态语言来说明和讲解。都讲的很多,这里就不再重复。
总结一下状态模式的使用,大体实现都是两步:
第一步:针对每种状态抽象各自的算法。使各算法可以互不影响。
第二步:提供统一入口。用于根据指定状态来替换算法。
最后来总结一下状态模式和策略模式的区别:
1、策略模式把选择权交给了玩家,而状态模式则封闭选择权。
2、策略模式是根据不同的选择选取对应的算法,而状态模式是根据状态的变化来选取对应的算法。
确实,可以把状态模式看成是一种自我封闭的策略模式。
版权声明:本文为博主原创文章,未经博主允许不得转载。