SiYangSimpleMvc
一个轻量级、最简、易用的Mvc框架。
零、MVC最简总结
一句话版:
Model 管数据,View 管显示,Controller 管交互与流程。
精确定义:
-
Model(模型):
负责业务规则与数据状态,不关心界面如何显示。 -
View(视图):
负责把 Model 的数据展示出来,不包含业务逻辑。 -
Controller(控制器):
接收用户输入,协调 Model 更新,并选择/驱动 View 刷新。
一、非MVC写法
1.1 例子
一个修改金币的例子
public class NotMvcDemo
{
private int coin = 0;
private TextMeshProUGUI coinText;
private void AddCoin(int addCount)
{
coin+=addCount;
coinText.text = $"{addCount}";
}
}
这个管理类里同时包含了:
1.状态(或数据),以下都称为状态,即金币数量coin;
2.包含了显示UI coinText;
3. 包含了修改方法AddCoin,更改了状态变化和显示变化;
状态、UI、控制方法耦合在一个文件里。
1.2 可优化地方
我们要让状态变化 和 显示变化 和 修改方法 三者分离。
让状态变化成为驱动整个流程的核心,而不是用修改方法命令一样的改变状态和显示。
二、MVC改造
2.1 先将最简单的View独立
[Serializable] public class MvcDemoView {public TextMeshProUGUI coinText; public Button addCoinBtn; // 调用方法修改view public void RenderCoinText(int currentCoint) { if (coinText!= null) { coinText.text = $"{currentCoint}"; } } }
2.2 状态
[Serializable]
public class MvcDemoData
{// SYMvcObservable是封装的数据变化通知,看2.3说明,当对值set就发通知
public SYMvcObservable<int> coin = new(); public void AddCoint(int addCoinCount) { coin.Value += addCoinCount; }}
2.3 数据变化通知
我们的目的是状态中的数据变化了,View就要随之更改,所以封装一个类做到这一点:
public sealed class SYMvcObservable<T>
{
private T _value; // 数据
public event Action<T> Changed; // 数据变化set,就执行Action
public SYMvcObservable(T initial = default) => _value = initial;
public T Value
{
get => _value;
set
{
if (Equals(_value, value)) return;
_value = value;
Changed?.Invoke(_value);
}
}
}
我们用SYMvcObservable对一条数据做一个封装,当数据set改变的时候,就执行Changed。
2.4 让Changed和修改View绑定
public static class BindUtil { /// <summary> /// 订阅 Observable 变化并立即渲染一次;自动把解绑动作登记到 disposer。 /// </summary> public static void Bind<T>(this SYMvcDisposer disposer, SYMvcObservable<T> obs, Action<T> render, bool renderImmediately = true) { if (obs == null || render == null) return; obs.Changed += render; disposer.Add(() => obs.Changed -= render); if (renderImmediately) render(obs.Value); }}
2.5 SYMvcDisposer类存储data和view的绑定,并且在合适的时机释放
// 缓存起来,在合适的时候统一释放
public sealed class SYMvcDisposer : IDisposable
{
private readonly List<Action> _undos = new();
public void Add(Action undo)
{
if (undo != null) _undos.Add(undo);
}
public void Dispose()
{
for (int i = _undos.Count - 1; i >= 0; i--)
_undos[i]?.Invoke();
_undos.Clear();
}
}
2.6 在Controller中创建data和view的绑定,和释放。
using System.Collections;
using System.Collections.Generic;
using SiYangMVC.Runtime;
using UnityEngine;
public class AddCointController : MonoBehaviour,IMvcController
{
private AddCoinModel _data = new();
[SerializeField] private AddCoinView _view;
// 暂时存储绑定关系,方便在某个时刻释放。
private SYMvcDisposer _disposer;
private void OnEnable()
{
Bind();
}
private void OnDisable()
{
Unbind();
}
public void Bind()
{
_disposer = new SYMvcDisposer();
_disposer.Bind(_data.coin , _view.RenderCoinText);
// 对Button的绑定
_disposer.OnClick(_view.addCoinBtn,()=>SetTouchTipVisible(5));
}
public void Unbind()
{
_disposer?.Dispose();
_disposer = null;
}
//----------api-------------
public void SetTouchTipVisible(int addCoint)
{
_data.AddCoint(addCoint);
}
}
MVC的C指Controller,在Controller中更新model,再更新view。
我们实现了一个数据绑定,更新model后,model会利用绑定的Action更新View。
957

被折叠的 条评论
为什么被折叠?



