Unity——观察者模式
2024-09-05 18:10:51
观察者模式
一、Demo展示
二、设计思路
我们假设一种情况,在app中修改了头像,在所有显示头像的UI中都需要更改相应的图片,一个个去获取然后调用刷新会非常麻烦;
因此我们需要一个自动响应机制——观察者模式;
核心:一个key对应多个Action(委托);
流程:
1.提前在每个需要响应的UI中添加监听事件;
2.修改数据同时注册观察者,需要参数可传参;
3.每一帧在LateUpdate中调用响应函数,把所有添加了注册了事件执行一遍;
三、关键类
1.带参数委托
由于参数类型不确定,所以使用object类型;
public delegate void obsAct(object args);
2.ObserverMa(单例)
字段:
private Dictionary<string, List<obsAct>> dicAll //存储所有事件和响应
private List<string> curAct = new List<string>();//存储当前帧注册的事件key值
private ArrayList objArgs = new ArrayList(); //存储key对应的参数
方法:
1)添加监听
public void AddListener(string key, obsAct act)
{
if (dicAll.ContainsKey(key))
{
dicAll[key].Add(act);
}
else
{
List<obsAct> actions = new List<obsAct>();
actions.Add(act);
dicAll.Add(key, actions);
}
}
2)注册事件
public void Register(string key,object args = null)
{
if (dicAll.ContainsKey(key))
{
curAct.Add(key);
objArgs.Add(args);
}
else
{
Debug.Log("未注册观察事件");
}
}
3)响应事件
public void Respond()
{
for (int i = 0; i < curAct.Count; ++i)
{
List<obsAct> acts = dicAll[curAct[i]];
for (int j = 0; j < acts.Count; ++j)
{
acts[j](objArgs[i]);
}
}
curAct.Clear();
objArgs.Clear();
}
四、测试类
这里为了方便,我只用了InputFiled和Text组件来完成;
InputFiled输入文字,结束时通知4个Text,Text显示输入的文字;
在Canvas上了脚本UIMa,UIMa的LateUpdate方法中调用了ObserverMa.I.Respond();
完整代码:
1.InputFiled
public class InputStr : MonoBehaviour
{
private InputField strInput;
private string str = "";
private bool isAdd = false;
private void Start()
{
strInput = GetComponent<InputField>();
}
void Update()
{
if (strInput.isFocused && !isAdd)
{
isAdd = true;
}
if (!strInput.isFocused && isAdd)
{
ObserverMa.I.Register(ObsStr.inputStr, strInput.text);
isAdd = false;
}
}
}
2.Text
public class Text1 : MonoBehaviour
{
public Text text;
private void Start()
{
text = GetComponent<Text>();
obsAct act = (str) => { text.text = str as string;};
ObserverMa.I.AddListener(ObsStr.inputStr,act);
}
}
五、优化方案
1.所有的key值可以自动使用const string 类替代,避免每次注册需要手动输入字符串,且容易出错;
2.无参委托和有参委托可以分开写,写两套重写的注册方法,数据也分开存储,减少Object = null的存储;
以上是我对观察者模式的理解,如果有更好的想法可以给我留言;
最新文章
- SharePoint 2013 Designer系列之数据视图筛选
- 勇者斗恶龙UVa11292 - Dragon of Loowater
- mongodb安装及基础命令
- 【代码笔记】iOS-传身份证号码可返回生日字符串
- 安装Odoo9出现的could not execute command ";lessc";问题
- 在xib里,拖一个UIView到UITableView中作为tableHeaderView
- yii2 访问控制
- Android如何监听蓝牙耳机的按键事件
- Java-继承的应用
- oracle查询每个表的占用空间
- postgrepsql 创建函数
- Fizz Buzz 问题
- 团队冲刺随笔合集—Beta阶段
- 巧用PHP数组函数
- 理解Python命名机制
- 更改Apache的首页
- Git 进阶之底层相关
- Spring 学习(十)--- Dispatch 分发逻辑
- IDOC 实例测试
- Python实践练习:strip()的正则表达式版本