藕这种东西大家都听说过吧?
耦合就是像耦一样的东西…藕断丝连.
你想想写代码如果像这样,黏在一起,会是好代码吗?
如果你想改点东西,都不知道哪里是哪里…
所以才有了解耦这种东西…来使我们的代码更美观和易于修改和维护
我作为一个小萌新躲在墙角里瑟瑟发抖,面对业内大佬的无数嘲讽目光和语言
我相信很多和我一样的萌新也是不敢问大佬了,很多都实在是很不友好.
为了更多的萌新…我写了这篇文章…
这是比较标准的网友式回答
耦合性:也称块间联系。指软件系统结构中各模度块间相互联系紧密程度的一种度量。模块之问间联系越紧密,其耦合性就越答强,模块的独立性则越差。模块间回耦合高低取决于模块间接口的复杂性、调用的方答式及传递的信息。
来自 https://blog.csdn.net/qq_39736982/article/details/81478176
就像是一对热恋的情侣…十分耦合…咳咳…相信我这是在讨论技术…我没驾照…
如何解耦合…就是如何拆散他们(狗粮护体),首先要直接硬上只会增进他们的情感
所谓
千里之堤,溃于蚁穴
应该从细节入手,先降低他们互相依赖的程度,让他们关系减淡,然后变成朋友…保持着一点点联系…
联系现实,我们的代码不也是这样…两个模块之间降低依赖程度,就是耦合度低了
但是依赖是不可避免的,就像人与人总是有联系
但是通过网络的中转,我们都依赖于网络沟通
我们本人直接联系就变少了,通过消息机制也可以让代码耦合变少
这只是解耦合方法的一种,方法千变万化,适合才是最好
来到了本文核心内容,消息机制
那么请思考,什么是消息机制?
还是上文那个小情侣…他们通过微信联系,那么微信发的就是消息
男: 亲爱的,星期日 我们 去 森林公园 玩吧
女: 好啊!不见不散
这就是消息,男的 约定了时间,地点,动作,对象
女方答应了,这个消息就变成了约定
穿过任意门回到代码中…
我们怎么实现这种约定
首先,我们要清楚实现什么
怎么区分是哪条消息?
可以用字符串或者枚举甚至int等多种类型
各有优点,字符串是方便,但是比对字符串会造成一点点性能问题
int会出现麻烦,数字id没有描述性,所以麻烦
枚举添加起来比较麻烦,不如字符串方便,但是可以使用位操作,性能比较好
所以我用了枚举标记一类事件
public enum EventList
{
Meet //约会的标志,23333333333333让我笑一会
}
引入一个概念,叫 容器
什么是容器,就像微信的数据库,容纳所有用户的消息.
我们也模拟一个容器试试,有很多选择
如List和Dictionary
但是Dictionary可以传入键值来标记事件,更方便
private static Dictionary<EventList, Delegate> EventPool = new Dictionary<EventList, Delegate>();
微信怎么实现,我们用一个类模拟
public class EventCenter : Singleton<EventCenter> //这个是单例模板,不会的同学可以学下
{
//这是消息中心,就是我们的微信
}
.
.
.
我们怎么约定消息的格式?
namespace 消息的动作
{
public delegate void ApplyEvent();
public delegate void ApplyEvent<T>(T prarm1);
public delegate void ApplyEvent<T, P>(T prarm1, P param2);
public delegate void ApplyEvent<T, P, W>(T prarm1, P param2, W param3);
public delegate void ApplyEvent<T, P, W, G>(T prarm1, P param2, W param3, G param4);
}
这就是执行的动作,“玩”
对象是谁,就是传入的参数,
为什么要用委托,如果女方突然想和男方玩,然后和男2号玩
只需要 委托+委托 = 新的复合委托
和男1玩 + 和男2玩 = 一个动作
这样就可以自动匹配传入的事件
public static void Add(EventList eventType, ApplyEvent Event)//传入一个枚举标记这个事件
{
switch (EventPool.ContainsKey(eventType)) //判断容器里有没有这个类型的事件
{
case true: //如果有
{
EventPool[eventType] = (ApplyEvent)EventPool[eventType] + Event; //委托中加入一个新的方法
break;
}
case false: //如果无
{
EventPool.Add(eventType, Event); //添加一个新的委托
break;
}
}
}
整个过程写的很清楚了,这就是约定一个事件
如何约定一个像上文提到的男12事件呢
不要中文命名,我这样只是为了好看
void Achievement()
{
EventCenter.Add(EventList.Test,和男1玩);
EventCenter.Add(EventList.Test,和男2玩);
}
void 和男1玩()
{
Debug.Log("女主和男1玩了");
}
void 和男2玩()
{
Debug.Log("女主和男2玩了");
}
这样EventList.Test就变成了一个约定的事件
等时间到了,如何执行这个事件
我们先定义一个这样的方法,其实 ?. 这个操作比这个更好
private static bool IsInDic(EventList eventType) //传入枚举标志
{
if (EventPool.ContainsKey(eventType)) //如果有这个事件
{
if (EventPool[eventType] != null) //如果这个事件不是空的
{
return true; //返回真
}
}
return false; //应付一下编译器
}
public static void Invoke(EventList eventType) //传入消息类型
{
if (IsInDic(eventType))//非空
{
ApplyEvent applyEvent = EventPool[eventType] as ApplyEvent; //拿出来这个事件
applyEvent(); //执行他...
}
}
就这样…女主和两个男主玩了
万一…男1不高兴了,女主临时取消了和男二玩的计划
public static void Remove(EventList eventType, ApplyEvent Event)
{
if (EventPool.ContainsKey(eventType))
{
EventPool[eventType] = (ApplyEvent)EventPool[eventType] - Event;
if (EventPool[eventType] == null)
{
EventPool.Remove(eventType);
}
}
}
就这样愉快地取消了,及得每次操作判断有木有这个事件
最后附带上本文全部源代码及拓展参数
转载请标明《伴风草的萌新学习之路》