前文:https://blog.csdn.net/Jaihk662/article/details/96895681(委托)
一、事件与委托
其实事件就是委托的一种升级版,和委托的不同如下:
- 在原有的委托变量的基础上多一个 event 关键字,这个委托变量就称为事件;
- 在其它类中,事件只能使用 +=、-= 来注册方法,而不能使用 = 为事件关联方法,相对于委托更加安全
一个例子如下(你也可以把它当成委托的一个应用场景):
功能:当你按下键盘K后,可以模拟每月的自动续费功能,返回一个消费账单
当你按下Z键后,可以清除当前所有的自动续费
PlayerCtro.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public delegate void Func(); //声明一个委托
public class PlayerCtro : MonoBehaviour
{
public Func func; //定义一个事件
public static PlayerCtro instance;
private void Awake()
{
instance = this; //继承于Mono的脚本单例写法,如果不是U3D环境,可以自己写个单例
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.K)) //当按下"K"键后
{
Debug.Log("你本月的消费账单如下:");
func();
}
if (Input.GetKeyDown(KeyCode.Z))
{
DelFunc();
if(func == null) //如果委托没有绑定任何方法
Debug.Log("你已成功取消所有的自动续费功能");
}
}
public void DelFunc() //清空委托绑定的所有的方法,需要 using System;
{
Delegate[] delFunc = func.GetInvocationList();
for (int i = 0; i < delFunc.Length; i++)
func -= delFunc[i] as Func;
}
}
Month.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Month : MonoBehaviour
{
private void Start()
{
PlayerCtro.instance.func += Yueka; //玩家开启月卡自动续费...
//PlayerCtro.instance.func = Yueka; 非法,事件只能在声明的类中使用"="号
}
public void Yueka()
{
Debug.Log("月卡:¥30");
}
}
二、观察者模式
设计模式:为了解决一些固定问题的代码套路
观察者设计模式(Observer):又称“发布-订阅模式”,是一种一对多的依赖关系,多个观察者对象同时监听某一个主题对象,当主题对象状态发生改变时,通知所有观察者
其实上面事件的例子,也可以算作一个非常简单的观察者模式的例子,另一个例子如下:
Subject.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public delegate void Func(string hint); //声明一个委托
public class Subject : MonoBehaviour
{
public Func func; //定义一个事件
public int index;
public static Subject instance;
private void Awake()
{
instance = this; //继承于Mono的脚本单例写法,如果不是U3D环境,可以自己写个单例
}
private void Start()
{
index = 905;
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.K)) //当按下"K"键后,模拟下一集更新
{
func(string.Format("名侦探柯南第 {0} 集已经更新", ++index));
}
}
}
Observer1.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Observer1 : MonoBehaviour
{
private void Start()
{
Subject.instance.func += Show; //模拟订阅
Debug.Log("你已经成功订阅视频:“名侦探柯南”");
}
public void Show(string hint)
{
Debug.Log("收到新消息" + hint);
}
}
运行结果: