StrangeIOC介绍

trangeIoC是一个专门为c#和Unity3D编写的控制反转(IoC)微框架。Strange是小型的、快速的、高度可扩展的,并且是为在项目变得更大、更复杂时变得更有用而专门构建的。

StrangeIOC Github地址

​ 框架只是一个工具,如果你希望一个框架能干所有的事情,但现实中是没有的。具体如何用如何理解需要自己不断的总结和重构,随着自己能力的提高会提升自己的编码和设计能力。

目标

​ 本次介绍Strange控制反转的核心原则,以及Strange是如何实现这些原则的。

Strange作者自己的一些想法

​ 就像Strange框架开发者所说Strange是一个可以被称为" opinionated framework"(固执的框架)。“Opinionated的意思是它假定做事情有正确和错误的方法,“Framework” 意味着Strange不仅仅是一个库或实用程序。它不是给你一个工具而是一个工具集。框架的意义在于指导您以“正确”的方式完成某些任务。Unity3D自身底层也是这样。

​ 以与其观点目标一致的方式使用固执己见的框架通常可以解决大量问题。对于Unity和Strange来说,这当然是正确的。试图使用一个框架,而不同意它的观点,往往会导致更多的困难。

​ 在这篇指南中,你会发现一些例子,在这些例子中,Strange的观点与Unity的观点发生了碰撞。在我看来,这很好。这意味着我的应用程序的绝大部分都是结构良好的,并且异常大多以一致的方式处理。

依赖注入

​ StrangeIoC中的“IoC”代表控制反转,依赖项注入是与该概念最密切相关的机制。那么什么是“控制”?“依赖”是什么?我们求的到底是什么?我们要注射什么?

先举个例子,下面就是一个依赖的例子,ShipModel依赖外部类 LaserGun,我们通过获取Gun的实例来调用他的公开的方法。

 public class ShipModel
    {
        public LaserGun Gun { get; set; }

        public void Attack()
        {
            Gun.Fire();
        }
    }

但是我们要是没有Gun的实例,那么程序就会报空指针异常。

我们常用的方法是新建一个对象 如下所示

public class ShipModel
    {
        private LaserGun Gun = new LaserGun();

        public void Attack()
        {
            Gun.Fire();
        }
    }

​ 毫无疑问,你已经做过很多次了这样的操作。这是一个很有吸引力的选项,因为它似乎消除了外部依赖并提供了封装。其实并不是这样,这是个坏主意。为什么呢?

​ 这就是紧密耦合的本质。通过在内部定义ShipModel所依赖的具体类,我们立即排除了这种关系的所有可能性。如果我们想要手枪而不是激光枪呢?如果我们想让其他班级知道枪的事呢?如果我们想要在整个应用程序中共享一个枪的实例呢?还是两个实例?

​ 您的类所依赖的任何东西都是依赖项。将其设为私有并在内部定义它并不会消除依赖性,而只是将其隐藏起来。您希望您的依赖项是可访问的和可更改的,这样您就可以尽可能地保持灵活性。

​ 对于这个问题有许多建议的解决方案。你可能知道他们中的一些(public setter、Signletons、factories)。Strange(以及类似的框架)的前提是通过注入来满足依赖性是正确的解决方案。

 public class ShipModel
    {
        [Inject]
        public IGun Gun { get; set; }

        public void Attack()
        {
            Gun.Fire();
        }
    }

​ 在上面的例子中,您可能从未见过的代码位是[Inject]标记。如果你忽略它,你会发现我所做的只是定义了一个普通的公共getter/setter。

​ 添加[Inject]标记表明这个类有一个需要填充的依赖项。我将在接下来的几段中向您展示具体的方法。

 public interface IGun
    {
        void Fire(); //An interface defines API, not implementation
    }

    public class LaserGun : IGun
    {
        public void Fire()
        {
            Debug.Log(“滋滋滋!”); //Implementation is in the concrete class
        }
    }

    public class BBGun : IGun
    {
        public void Fire()
        {
            Debug.Log(“Biu Biu Biu!”);
        }
    }

    public class WaterPistol : IGun
    {
        public void Fire()
        {
            Debug.Log(“哗哗哗!”);
        }
    }

    public class SuperGun : IGun
    {
        public void Fire()
        {
            Debug.Log(“灭霸打了个响指!”);
        }
    }

所以我们在看之前的ShipModel类,我有一个枪械库,开始我想用水枪,过会我想换个武器,用用激光枪。最后我还想试试超级无敌枪——灭霸的响指。如果IGun是一个单例的话会怎么赋值呢?每次换武器的时候重新赋值一个枪吗?现在就展现出单例的缺点了。当然单例在某些情况下是很有用的。但是单例使用多了会增加你的项目依赖程度,后期很难维护和修改。

public class ShipModel
    {
        [Inject]
        public IGun Gun { get; set; }

        public void Attack()
        {
            Gun.Fire();
        }
    }

在Strange中就可以这样去注入枪的依赖,不关心具体实现类。这可能看起来很简单,因为我们的示例很简单。但是想象一下这些依赖的几十个,成百上千个。每个具体的依赖项都会稍微降低代码的灵活性。您的应用程序越大,您就越需要管理这个不断扩大的依赖圈。

那么我们需要在哪里进行绑定操作呢?答案是Context

 injectionBinder.Bind<IGun>().To<WaterGun>();

上面这样的绑定会在每次注入的时候都会生成一个WaterGun的示例。

如果我们想在游戏中只有一个水枪实例怎么办呢?

 injectionBinder.Bind<IGun>().To<WaterGun>().ToSingleton();

那么下面介绍一下Strange的整个流程

在这里插入图片描述

1.ContextView是一个MVCSContext的实例,它继承了MonoBehavior。

2.当在框架Start内发送信号给Command,框架进行初始化。

3.Mediators通过派发信号来与Command进行通讯。

4a.Command派发信号给Mediator

4b.Command对service和Model的API进行逻辑等操作。

5.Services通过command来对Model内的数据进行更新和设置。

6.Models和Services可能会给Mediators派发一些消息。

Views只跟Mediators进行通讯,View只处理跟Unity相关的操作,不要增加其他依赖。

明天跟大家分享一下Signal 和Command。

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
前言 unity的框架,除了各大公司自己内部使用的,开源并好用的实际并不是很多,我会慢慢挖掘,依次写出自己的一点见解,错误的地方,望各路大神指正。 一、基本概念 控制反转(Inversion of Control,英文缩写为IOC),我的理解就是,原本A类要获取B类的对象,需要你在A类中自己New一个对象,那么是由A来获取并控制B的对象,IOC就是把对象获取的这个过程交给容器和依赖注入来处理,A类并不知道B的对象是哪里来的,对B对象的控制,由自己变成了其他类,官方一点的概念可以百度,这个还是蛮多的。 二、StrangeIOC基础类型 实际要理解一个框架的类型,还是要自己看源码,这里我只说一下几个重要类型的作用,这个看源码的时候有个印象,也方便理解,而且说这部分的帖子也很多,我就不再赘述了。 1.Context 上下文组件定义程序边界,也就是可以把一个程序定义成多上下文,让代码更加模块化 它提供了程序入口,也算是框架中耦合度最高的地方 2.Binder和Binding 这两个类是这个框架最重要的组成部分 Binding存储了对象的绑定关系,而Binder存储了Binding的对象 3.View和Mediator MVCS中的View层,View只用于显示,也就是View只负责管理UI,Mediator负责界面逻辑,事件响应等 4.Model MVCS中的Model层,负责数据部分 5.Command MVCS中的Control层,负责执行逻辑代码 6.Service MVCS中的Service层,负责与第三方交互,这个Service我理解的,并不是一定指代服务器,也可以是其他的软件,什么都可以,它就是我们程序对外的接口 7.Dispatcher 派发器是框架内通信主线的其中一种,用来派发消息,触发命令,从而进一步解耦 8.Signal 信号是框架内另外一种通信主线,它采用强类型,来绑定信号和命令之间的关系,实现消息响应的触发 9.ReflectionBinder 反射部分,通过binding来获取类的信息,存储在ReflectedClass中 10.injector 注入器,通过反射获取的信息,来实例化请求的对象 --------------------- 作者:蓝天小僧 来源:CSDN 原文:https://blog.csdn.net/zcaixzy5211314/article/details/80876228 版权声明:本文为博主原创文章,转载请附上博文链接!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值