介绍

先举一个简单的例子:

在UGUI中新建一个Button和Text,要求实现点击Button改变Text中的文字。

我的第一反应就是在Button上添加一个脚本,获取点击事件来改变Text的内容。

或者在Text和Button上都添加一个脚本,Text设置为单例模式,Button点击事件触发Text中的改变文字方法。

可是这两种方法要不就是关联度太高协作开发时很不好,要不在大项目中用很多单例模式很不好。

这时就需要到了解耦合技术!!!


高度解耦合就是利用事件的监听、事件的广播、委托来实现的。

无参实现

例如上面点击按钮切换的实现。

先写3个需要之后调用的类。

EventType

//这里面放的是一个枚举类型的事件码,就是用来表示按钮点击事件触发的函数
public enum EventType
{
ShowText,
}

CallBack

//这里面放的是所有不同参数类型的委托
public delegate void CallBack();
public delegate void CallBack<T>(T arg);

EventCenter

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class EventCenter
{
//定义一个字典存放 事件码 和 委托
private static Dictionary<EventType, Delegate> m_EventTable = new Dictionary<EventType, Delegate>(); //无参的添加事件监听
public static void AddListener(EventType eventType,CallBack callBack)
{
//先判断是否包含
if (!m_EventTable.ContainsKey(eventType))
{
m_EventTable.Add(eventType, null);
}
//判断要添加的委托和已有的类型是否相同,只有相同才可以添加
Delegate d = m_EventTable[eventType]; //key为eventType的value
if (d != null && d.GetType() != callBack.GetType())
{
throw new Exception(string.Format("尝试为事件{0}添加不同的委托,当前事件所对应的委托为{1},要添加的委托类型为{2}", eventType, d.GetType(), callBack.GetType())); } //要添加的委托和已经存在委托一致了
//关联一下
m_EventTable[eventType] =(CallBack) m_EventTable[eventType] + callBack;
} //无参的移除监听
public static void RemoveListener(EventType eventType, CallBack callBack)
{
if (m_EventTable.ContainsKey(eventType))
{
Delegate d = m_EventTable[eventType];
if (d == null) //为空表示事件码没有对应的委托
{
throw new Exception(string.Format("移除监听错误,事件{0}没有对应委托", eventType));
}
else if (d.GetType() != callBack.GetType()) //判断委托类型是否一致,一致才能移除
{
throw new Exception(String.Format("移除监听错误,尝试为事件{0}移除不同类型的委托,当前委托类型为{1},要移除的委托类型为{2}", eventType, d.GetType(), callBack.GetType()));
}
}
else //不存在事件码
{
throw new Exception(String.Format("移除监听错误,没有事件码{0}", eventType));
} //可以移除
m_EventTable[eventType] = (CallBack)m_EventTable[eventType] - callBack; if (m_EventTable[eventType] == null) //如果为空了,移除事件码
{
m_EventTable.Remove(eventType);
}
} //无参的广播监听
public static void Broadcast(EventType eventType)
{
//把事件码对应的委托取出来,调用一下委托
Delegate d;
if(m_EventTable.TryGetValue(eventType,out d)) //尝试获取该键的值
{
CallBack callBack = d as CallBack; //当参数不匹配时会强转失败
if(callBack != null)
{
callBack();
}
else
{
throw new Exception(String.Format("广播事件错误,事件{0}对应委托有不同的类型,", eventType));
}
}
}

ShowText

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ShowText : MonoBehaviour
{
//给方法添加监听,设置一个码
//点击时只需要广播一下事件码
void Start()
{
gameObject.SetActive(false);
EventCenter.AddListener(EventType.ShowText, Show); //添加监听
} private void OnDestroy()
{
EventCenter.RemoveListener(EventType.ShowText, Show);
} private void Show()
{
gameObject.SetActive(true);
GetComponent<Text>().text = "Hello";
}
}

BtnClick

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; public class BtnClick : MonoBehaviour
{ void Start()
{
//Lambda表达式
GetComponent<Button>().onClick.AddListener(()=>{
EventCenter.Broadcast(EventType.ShowText); //广播事件
});
}

有参和无参基本都是一样的,只是泛型那里添加个类型就好了,不再一一写了

Unity---高度解耦和的更多相关文章

  1. 可复用且高度解耦的iOS用户统计实现

    http://www.cocoachina.com/ios/20160421/15912.html 本文为投稿文章,作者:编程小翁(简书) 用户统计 用户行为统计(User Behavior Stat ...

  2. 通过Unity依赖注入

    前言 Unity容器的思想起始于我在为Web Client Sofitware Factory项目工作的时候,微软的patterns&practices团队已经使用依赖注入的概念好几年了在那时 ...

  3. Unity学习系列一简介

    一.简介 Unity的目标是为了提升"依赖注入"的思想,去建立更加松耦合的系统.patterns & practices 小组在那个时候实现DI的方式和我们现在认为的DI有 ...

  4. 15个具有高度影响力的Apache开源项目

    自1999年创立以来,Apache软件基金会如今已成了众多重要的开源软件项目之家.其中成功的项目有Geronimo,有Tomcat,有Hadoop,有如今成了大数据王国关键车毂的分布式计算系统. 虽然 ...

  5. ASP.NET CORE 内置的IOC解读及使用

    在我接触IOC和DI 概念的时候是在2016年有幸倒腾Java的时候第一次接触,当时对这两个概念很是模糊:后来由于各种原因又回到.net 大本营,又再次接触了IOC和DI,也算终于搞清楚了IOC和DI ...

  6. zerojs! 造出最好的 CMS 轮子

    zerojs是一个基于nodejs.angularjs.git的CMS.在它之上可以继续开发出博客.论坛.wiki等类似的内容管理型系统. 拥抱开发者和社区 层次清晰,高度解耦.前后端即使分开也都是完 ...

  7. Flux 普及读本

    话说当时做 APP 时,三月不知肉味,再次将眼光投放前端,有种天上一天,地下一年的感觉. Flux 是一种思想 了解的最好方式当然是看Flux官方文档了.React 中文站点也能找到对应的翻译版本,但 ...

  8. 安卓v7支持包下的ListView替代品————RecyclerView

    RecyclerView这个控件也出来很久了,相信大家也学习的差不多了,如果还没学习的,或许我可以带领大家体验一把这个艺术般的控件. 项目已经同步至github:https://github.com/ ...

  9. 【转】理解 PHP 依赖注入 | Laravel IoC容器

    Laravel框架的依赖注入确实很强大,并且通过容器实现依赖注入可以有选择性的加载需要的服务,减少初始化框架的开销,下面是我在网上看到的一个帖子,写的很好拿来与大家分享,文章从开始按照传统的类设计数据 ...

  10. Vue 入门指南

    英文:http://vuejs.org/guide/index.html 介绍 vue.js 是用来构建web应用接口的一个库 技术上,Vue.js 重点集中在MVVM模式的ViewModel层,它连 ...

随机推荐

  1. [原创]Java项目统一UTC时间方案

    Java项目统一UTC时间方案 作者:Gods_巨蚁 引言 近期团队的个别项目在进行框架升级后,部分时间值存在8小时误差,原因是错误的将数据库中的时间数据理解成了UTC时间(旧版本认为是北京时间) 考 ...

  2. java堆栈区别(个人理解)

    java把内存分为2种,一种是堆内存,一种是栈内存. 堆内存:通过new关键字出来的对象放在堆内存中,堆内存可以动态的分配内存大小,垃圾回收器自动回收不再使用的数据,由于动态分配内存所以存取的速度较慢 ...

  3. POJ1012(约瑟夫问题)

    1.题目链接地址 http://poj.org/problem?id=1012 2k个人,前面k个是好人,后面k个是坏人,找一个数t,每数到第t时就去掉,使所有坏人在好人之前被杀掉. 思路:约瑟夫公式 ...

  4. 【FZU2280】Magic

    题意 给出n个字符串,每个字符串有一个权值wi 有q个操作,操作有两种 1 x y 将字符串x的权值变为y 2 x 查询操作,输出以字符串x为后缀,且权值小于等于wx的字符串个数.其中n<=10 ...

  5. Linux修复MBR扇区故障

    给虚拟机增加一块硬盘,用于备份mbr的信息 fdisk -l 查看硬盘系统是否认识 fdisk /dev/sdb 进行分区 fdisk -l 查看分区是否出来 mkfs -t ext4 /dev/sb ...

  6. Druid配置属性列表及含义

    前两天,在排查springBoot使用双数据源出现的运行一段时候出现了数据库连接断开的问题的时候,查了很多关于Druid数据库连接池配置的文章,虽然最后问题的原因不是属性配置的问题,也可以说是 属性配 ...

  7. Codeforces 427E Police Patrol

    找中间的数,然后从两头取. #include<stdio.h> ; int pos[MAX]; int main() { int n,m,tmp; int i; int pol; long ...

  8. Python 面向对象class(2)

    Python 面向对象 Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的.本章节我们将详细介绍Python的面向对象编程. 如果你以前没有接触过 ...

  9. Mac10.9下的libtiff编译

    libtiff介绍 libtiff下载 libtiff编译 libtiff介绍? 参考:http://en.wikipedia.org/wiki/Tiff libtiff下载 直接到官网下载:http ...

  10. Linux网络编程IPv4和IPv6的inet_addr、inet_aton、inet_pton等函数小结(转)

    原文:http://blog.csdn.net/ithomer/article/details/6100734 知识背景: 210.25.132.181属于IP地址的ASCII表示法,也就是字符串形式 ...