StangeIOC Signal and Command 信号和命令

StangeIOC Signal and Command 信号和命令

信号和命令(Signals and Commands)

信号和命令在Strange里是两个独立的体系,通过绑定来将两者结合到一起。

信号(Signals)

信号是Strange内的一个通讯工具。通过信号可以添加监听,也可以派发消息事件。

public class LevelBeginSignal : Signal<int>{};

LevelBeginSignal signal = new LevelBeginSignal();

signal.AddListener(LevelBeginHandler);

public void LevelBeginHandler(int level)
{
	Debug.Log("We're beginning Level " + level);
}

signal.Dispatch(6);    //Logs "We're beginning Level 6"

信号最多支持4个泛型参数,信号可以绑定不同或者相同的类型。

public class ButtonClickedSignal : Signal{};
public class GameObjectNameChangeSignal : Signal< GameObject, string>{};
public class BandAgeUpdateSignal : Signal<int, int, int, int>{};

ButtonClickedSignal.Dispatch();
GameObjectNameChangeSignal.Dispatch(gameObject, newName);
BandAgeUpdateSignal.Dispatch(19, 22, 20, 22); 

如果你想要使用更多的参数,可以使用数据结构体或者类的形式来进行传参操作。

信号若是加上Strange框架内的依赖注入功能,那么就可以有很神奇的功能。

injectionBinder.Bind<LevelBeginSignal>().ToSingleton();

public class SomeClass
{
   [Inject]
   public LevelBeginSignal signal { get; set; }
   [PostConstruct]
   public void PostConstruct()
   {
  	signal.AddListener(LevelBeginHandler);
   }
   private void LevelBeginHandler(int level)
   {
  	Debug.Log("SomeClass received level " + level);
   }
}

public class SomeOtherClass
{
   [Inject]
   public LevelBeginSignal signal { get; set; }
   [PostConstruct]
   public void PostConstruct()
   {
  	signal.AddListener(LevelBeginHandler);
   }
   private void LevelBeginHandler(int level)
   {
  	Debug.Log("SomeOtherClass received level " + level);
   }
}

public class YetAnotherClass
{
   [Inject]
   public LevelBeginSignal signal { get; set; }
   
   public void SomethingHappened()
   {
  	signal.Dispatch(42);  //Logs "SomeClass received level 42" and
                                       //"SomeOtherClass received level 42)"
   }
}

LevelBeginSignal信号通过绑定操作之后,通过依赖注入,那么我可以在任意类内注入信号,并且对信号进行操作。上面代码示例中,我在SomeClass和SomeOtherClass中添加了对LevelBeginSignal的监听,然后YetAnotherClass中发送开始42关的消息,SomeClass和SomeOtherClass都收到了开始42关的消息,执行了响应的监听函数。

命令(Commands)

命令在Strange内定义是程序书写逻辑的地方。每个命令就像是一个独立的方法。命令通常没有状态,意味着它不保留任何信息。只管做他自己需要做的事,然后结束。命令核心的方法就是Execute,当命令被执行的时候,Excute方法就被调用执行。

public class MyCommand : Command
{
   override public Execute()
   {
  	Debug.Log("By your Command");
   }
}

命令可以做任何事情,更新场景物体,更新服务,更新模型,升级等等。命令的关键点是你程序内的动作。

Retain()

命令一般执行完事生命周期就结束了,但是对一些需要时间等待的命令就会有一些问题。例如我向服务器请求一个数据列表,我刚执行没等服务器给我反馈命令的生命周期就结束了。Retain方法就是来保持Command的生命周期。当你接收到服务器的反馈后,再执行Release()函数来释放命令的生命周期。

public class MyCommand : Command
{
   [Inject]
   public IService service { get; set; }
   override public Execute()
   {
  	Retain();
  	service.CallOutToAServer().Then(DoAnotherThing);
   }
   private void DoAnotherThing()
   {
  	Release();
   }
}

上面方法中涉及到Promise的用法,这个是Strange拓展的一个功能,功能参照Promise/A规范。

下面说说咱们文章的关键了。

信号命令的绑定

public class MySignal : Signal<string>{}

public class MyCommand : Command
{
   [Inject]
   public string MyString { get; set; }

   override public Execute()
   {
  	Debug.Log(MyString);
   }
}

commandBinder.Bind<MySignal>().To<MyCommand>();

上面例子最后一行代码中实际上 是做了三件事

1.将信号绑定为单例,这样它就可以在任意地方进行注入操作。

2.实例化并执行命令。

3.信号可以将参数注入到命令中。

示例中的 MyString就是信号的参数,Strange底层进行了对此数据的绑定操作,无需手动进行其他操作。

这样我们就把实现下面的示例,通过命令来执行了。

public class MyClass
{
   [Inject]
   public MySignal signal { get; set; }

   public PostConstruct()
   {
  	signal.Dispatch("Hello Command");  //Logs: "Hello Command";
   }
}

通过这样就可以实现解耦操作了,可能类的数量会增加很多,信号和命令,但是相互之间的关系独立起来了。

commandBinder.Bind<GameStartSignal>().To<GameStartCommand>();

commandBinder.Bind<GameStartSignal>().To<LoadAndConfigureLevelCommand>();

commandBinder.Bind<GameStartSignal>()
   .To<LoadLevelCommand>()
   .To<ConfigureLevelCommand>()
   .To<GameStartCommand>().
   .InSequence() ;

commandBinder.Bind<GameStartSignal>().To<LoadAndConfigureLevelCommand>().Once();

上面示例中前两行代码都是绑定GameStartSignal信号,但是这样的写法可能比较繁琐。而且阅读起来也很差,并且相互之间的执行顺序可能也并不清晰。

再下面的一行可能大家发现了一个新的函数InSequence,这个函数是代表信号所绑定的各个命令之间的执行顺序为依次执行,前一个执行完再执行下一个,知道完全结束。若不加InSequence,那么代表命令为并行执行的关系。

最后一行中有一个Once的函数,此函数代表当前命令仅执行一次,执行完成后,再也不执行此操作。适用于一些初始化的操作。例如文件读取,程序配置等(重置功能不要使用此方法)。

注意事项

信号绑定命令的时候,参数不可以为同一类型的,若是如此,在注入命令中的时候会报错。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值