18.指挥官只有一个——单件模式
2012-07-18 10:43
316 查看
随着游戏开发的进展,有人建议添加一个新的玩法——保护指挥官;游戏剧情是这样的,在游戏中有一位重要人物,玩家必须保护他,如果他的被干掉了,也就意味着Game Over。
创建新的游戏单位,这项工作当然又落到了你的身上。根据你对游戏代码的了解,很快就创建了指挥官的相关代码,首先是在EUnit枚举中添加成员:
''游戏单位标识枚举 Public Enum EUnit … Commander = 1004 '指挥官 … End Enum |
''指挥官 Public Class CCommander Inherits CUnit Public Sub New() myBehavior = New CLandBehavior myWeapon = New CNoWeapon mySpeed = 14 Name = "指挥官" UnitId = EUnit.Commander End Sub End Class |
''陆地单位创建者 Public Class CLandUnitCreator Inherits CUnitCreator Public Overrides Function CreateUnit(ByVal unitType As EUnit) As IUnit Select Case unitType ... Case EUnit.Commander Return New CCommander ... End Select End Function End Class |
但很快,项目经理就来了,“对指挥官角色的创建,你就没有一点限制?我刚才看见了一个方阵的指挥官,要知道,指挥官只能有一个!”
“哦,好的,老大,马上修改代码!”。就知道事情没这么简单!
正好是午餐时间,还是先吃饭吧,毕竟人是铁,饭是钢。午餐时,有个兄弟得意地说到了关于很多指挥官的故事;不过,更多好心的兄弟姐妹们都在帮助你考虑如何修改指挥官角色的创建,有人提到了“单件模式”,好主意!
应用单件模式
先来看看单件模式(Singleton Pattern)的定义:确保一个类只有一个实例,并提供一个全局访问点。只有一个实例,这正是我们想要的。
好了,既然定义中提到了“一个全局访问点”,我们就先创建这个访问点;那么,这个访问点是什么呢?我们知道,在VB.NET中的类类型中只有一个副本的成员是它的共享成员(Shared),所以,我们就在CCommander类中创建这个共享成员,定义如下:
Public Class CCommander Inherits CUnit Public Shared Commander As IUnit = Nothing ... End Class |
接下来,需要保证这个类只能创建有一个实例,我们创建一个共享方法来实现,这样,CCommander类的代码就是下面这样:
Public Class CCommander Inherits CUnit Public Shared Commander As IUnit = Nothing Public Sub New() myBehavior = New CLandBehavior myWeapon = New CNoWeapon mySpeed = 14 Name = "指挥官" UnitId = EUnit.Commander End Sub Public Shared Function CreateUnit() As IUnit If IsNothing(Commander) Then Commander = New CCommander End If Return Commander End Function End Class |
在创建指挥官单位实例的方法CreateUnit()中,代码很简单,我们使用IsNothing()方法判断Commander是否已经实例化,如果没有就使用New关键字实例化这个对象;当然,如果已经创建了,就不用再做什么了。最后,方法将返回Commander对象。
现在,我还需要修改CLandUnitCreator类中的代码,我们现在不能使用New CCommander语句创建指挥官角色了,而是要使用CCommander.CreateUnit()方法。代码如下:
''陆地单位创建者 Public Class CLandUnitCreator Inherits CUnitCreator Public Overrides Function CreateUnit(ByVal unitType As EUnit) As IUnit Select Case unitType ... Case EUnit.Commander Return CCommander.CreateUnit ... End Select End Function End Class |
现在,我们可以测试这个单件是否起作用了,代码如下:
Module Module1 Sub Main() Dim landUnitCreator As New CLandUnitCreator Dim cmd1 As IUnit = landUnitCreator.CreateUnit(EUnit.Commander) cmd1.Name = "XXX将军" Console.WriteLine(cmd1.Name) cmd1.Move(100, 100) cmd1.Attack(110, 110) Dim cmd2 As IUnit = landUnitCreator.CreateUnit(EUnit.Commander) Console.WriteLine(cmd2.Name) Console.ReadLine() End Sub End Module |
本代码运行的结果如下图:
代码中,我两次调用了创建Commander的方法;第一次,创建了cmd1,我们将指挥官的名字(Name)设置为“XXX将军”(请注意,在构造方法中他的默认名称是“指挥官”);第二次,我们创建了cmd2,这时我们并没有设置他的名字,如果他和cmd1不是一个实例的话,显示的名字应该是“指挥官”,不是吗?
实际上,我们看到,cmd2显示的名字依然是“XXX将军”,这说明cmd1和cmd2实际上表示的是同一个Commander实例。我们的单件模式应用成功了,Yeah!
提交代码时记得提醒老板,一样要一如继往地要求大家使用创建者类中的CreateUnit()方法创建游戏单位;否则的话,你懂的。
小结
我们在本章应用了单件模式,讨论了如何对一个类只创建一个实例,我们成功地创建了唯一的指挥官角色。此外,在使用单件模式时,还有一个需要注意的问题就是:如果我们在多线程系统中使用了单件对象,还必须考虑不同线程下对于这个单件对象的引用同步问题;这时,我们可以在使用单件对象时使用SyncLock语句对其进行同步锁定。
各种士兵和装备训练了这么久,我们终于要横渡海峡向敌人发起进攻了,登陆时注意不要让敌人的炮火击中运输机和运输船了,否则后果很严重的。
在下一章,我们将了解观察者模式。
出自:http://www.caohuayu.com/books/B0003/B0003.aspx
相关文章推荐
- 确保类只有一个唯一对象,单件模式
- Web项目中使用NLog记录日志,利用单件模式控制整个项目只有一个Logger对象的问题
- 只有一个公网IP也可以使用LVS的DR模式!
- 单例模式确保某个类只有一个实例
- 单件模式带来的一个小麻烦
- 使用java Reflection机制使单例模式不再只有一个对象的实例
- 单例模式——仓库只有一个
- 用泛型做一个通用的单件模式
- 定义一个单例模式的类,在这个类中,只有唯一的实例,不能new出来其他的实例对象。
- 设计模式-Singleton模式(只有一个实例)
- 只有一个公网IP也可以使用LVS的DR模式!
- python实现单例模式,从始至终都只有一个实例
- C++设计模式5--单例模式Singleton--当前对象只有一个实例 .
- csdn可能待改进点之18------>我没有一个分类叫“体验并改进CSDN(16)”, 只有叫“体验并改进CSDN”的
- 只有一个公网IP也可以使用LVS的DR模式!(外带php session粘滞问题解决)
- 单例模式--确保一个类只有一个实例,并提供一个全局访问点。
- 只有一个公网IP也可以使用LVS的DR模式!(外带php session粘滞问题解决)
- Java设计模式(5)Singleton模式 只有一个实例
- 单例模式--只有一个实例
- C++设计模式5--单例模式Singleton--当前对象只有一个实例