Unity StrangeIoC(一)
正式之前先说说基础的概念:
首先是MVC框架,MVC框架的思路是将业务逻辑、数据、界面显示分离,网上很多关于MVC的资料,这里不再过多的描述了。
下面截图来自wikipedia的mvc框架:
然后是控制反转(包括依赖注入和依赖查找),控制反转也是著名框架spring框架的核心。
对于控制反转(Inversion of Control,缩写IOC)的依赖注入,先用一个C#示例代码演示一下。比如设计一个玩家攻击敌人的游戏,玩家可以装备手枪,步枪。最简单的代码设计实现如下:
public
class
Player
{
public
string
gunName =
"ShouQiang"
;
public
void
Attack(Enemy enemy)
{
if
(gunName ==
"ShouQiang"
)
enemy.hp -= 10;
else
if
(gunName =
''
BuQiang")
ememy.hp -= 20;
}
}
如上述代码,假如项目中多了一个(机枪),需要重写player类,重写攻击逻辑(if..else)设计不合理。重新设计,代码可以用下面的方实现:
public
interface
IGun {
voidAttack(Enemy eneny);
}
public
class
ShouQiang : IGun
{
public
void
Attack(Enemy eneny)
{
enemy.hp -=10;
}
}
public
class
BuQiang : IGun
{
public
void
Attack(Enemy enemy)
{
enemy.hp -= 20;
}
}
public
class
Player
{
public
IGun gun = newShouQiang();
public
void
Attack(Enemy enemy)
{
gun. Attack(enemy);
}
}
public
class
Eneny
{
public
int
hp;
}
如果再增加机枪,直接增加一个机枪类继承IGun接口就可以了 playe类中
public IGun gun = new ShouQiang();简单实现了一个注入.
下面正式介绍strangeioc.
正如strangeioc描述的一样,总体上说它是根据控制反转和解耦和原理设计的,支持依赖注入. 继续引入一个示例,如果写一个单玩家游戏,死亡后将最高分数提交到facebook ,代码如下:
public
class
MyShip: MonoBehaviour {
private
FacebookService facebook;
private
int
myScore,
void
Awake()
{
facebook = FacebookService.getlnstance(),
}
void
onDie()
{
if
(score > highScore)
facebook.PostScore(myScore),
}
}
这样做有两个问题:
1.ship作为控制角色,但是除了要通知facebook上传分数还要处理代码逻辑.将自身与游戏逻辑与 facebook逻辑关联(髙耦合)
2.FacebookService是单键,如果我们改为要提交到Twitter..or Google+... 怎么办?或者FacebookService里面的方法有变更怎么办?
如果代码如上,需要重构很多代码才能完成相应的功能,但是通过引入ioc,重构将会方便很多。
public
class
MyShip : MonoBehavior
{
void
OnDie()
{
dispatcher.Dispatch(GameEvent.SHIP_DEAD);
}
}
视图模块出发了死亡逻辑,它(View)需要知道的仅仅是这些就够了,然后将死亡消息发送出去。
某个模块的代码用来接收死亡消息,然后做出处理,如下:
public
class
OnShipDeathCommand: EventCommand
{
[Inject]
ISocialService socialService {
get
,
set
,}
[Inject]
IScoreModel scoreModel {
get
set
,}
public
override
void
Execute()
{
if
(scoreModel.score > scoreModel.highScore)
socialService.PostScore(scoreModel.score);
}
}
[Inject]标签实现接口,而不是实例化类
#if UNITY_ANDROID
injectionBinder.Bind<ISocialService>().To<GoogleService>().AsSingleton();
#else
injectionBinder.Bind<ISocialService>().To<FacebookService>().AsSingleton();
#endif
//...or...
//injectionBinder.Bind<ISocialService>().To<MultiServiceResolver>().AsSingleton();
injectionBinder.Bind<IScoreModel>() To<ScoreMcxiel>() AsSIngleton();
commandBinder.Bind(GameEvent.SHIP_DEAD , OnShipDeathCommand);
用IOC(控制反转)我们不用关注具体逻辑,也不同自己再创建单键。
ship触发Command来执行逻辑,每个模块之间都是独立的。
1>
commandBinder.Bind(GameEvent.SHIP_DEAD , OnShipDeathCommand);
将事件和对应逻辑绑定在了一起。