前言:
该文章有两篇《unity自制模式(MVC与命令模式相结合)(1)》与《unity自制模式(MVC与命令模式相结合)(2)》直达下一篇(2)
本框架实行MVC结构且附带命令模式进行搭建,简单称述:
(1)首先Canvas中UI面板作为View的显示;
(2)UIEventArgs作为UI面板的Model层;
(3)Handler作为UI面板的控制单元;
(4)Command作为UI面板的命令层,View层会发送消息并附带Model给Handler,Handler将指定给命令。
注:该结构将MVC分层明确,并附带命令,可实现面板的数据进行撤销与反撤销功能。
一、UML图
该图构建比较潦草,如想要具体了解,可以继续阅读并在下一篇(2)文章中实践一下。
二、框架说明
这个框架的主要组成部分和功能:
1. **ICommand**:定义了执行和撤销命令的接口。
2. **IEventArgs**:定义了事件参数的接口,包括事件类型和处理程序名称。
3. **IHandler**:定义了处理事件参数和发送消息的接口。
4. **IUIEvent**:定义了发送和接收 UI 事件的接口。
5. **Singleton<T>**:实现了单例模式的模板类,确保每个类只有一个实例。
6. **AbsCommand**:抽象类,定义了执行和撤销命令的抽象方法。
7. **CommandHandler**:命令处理程序,负责管理执行、撤销和重做命令。
8. **UIEventHandler**:UI 事件处理程序,负责注册处理程序和 UI 事件,并处理事件参数和消息。
9. **AbsUIEventArgs**:UI 事件参数的抽象类,定义了事件类型和处理程序名称。
10. **AbsUIEvent**:UI 事件的抽象类,定义了发送和接收 UI 事件的虚拟方法。
11. **AbsHandler**:处理程序的抽象类,定义了处理事件参数和发送消息的抽象方法。
12. **SimpleHandler<T>**:简单处理程序的模板类,实现了处理程序的基本功能。
13. **ConcretePanel1**:具体 UI 事件类,实现了特定类型的 UI 事件。
14. **ConcretePanelCommand1**:具体命令类,实现了特定类型的命令。
15. **ConcretePanelArgs1**:具体 UI 事件参数类,定义了特定类型 UI 事件的参数。
16. **ConcretePanelHandler1**:具体处理程序类,实现了特定类型处理程序的功能。
17. **CommandType**:命令类型的枚举,用于标识不同类型的命令。
18. **HandlerUtilities**:处理程序工具类,提供处理程序的一些辅助功能。
19. **UIPanelManager**:UI 面板管理器,管理具体的 UI 面板和参数。
这些类组成了一个基于命令模式和事件驱动的系统框架,通过统一的接口和抽象类,实现了系统的灵活性和可扩展性。
三、程序展示
1、接口定义:
(1)ICommand:
public interface ICommand
{
void Execute();
void UnExecute();
}
(2)IEventArgs:
public interface IEventArgs
{
Type type { get; }
ushort HandlerName { get; }
}
(3)IHandler:
public interface IHandler
{
void Dispose(IEventArgs args);
void SendMessage(params object[] args);
}
(4)IUIEvent:
public interface IUIEvent
{
void SendEvent(IEventArgs args);
void Receive(ushort sender, params object[] data);
}
(5)Singleton单例
public class Singleton<T> where T : new()
{
private static T _Instance = new T();
protected Singleton()
{
Debug.Assert(null == _Instance);
}
public static T Instance
{
get { return _Instance; }
}
}
2、命令撤销与还原的实现
(1)CommandHandler :
public class CommandHandler : Singleton<CommandHandler>
{
private Stack<ICommand> undoCommands = new Stack<ICommand>();
private Stack<ICommand> redoCommands = new Stack<ICommand>();
/// <summary>
/// 是否正在撤销
/// </summary>
/// <returns></returns>
public bool isUndoing;
/// <summary>
/// 是否正在恢复撤销
/// </summary>
public bool isRedoing;
/// <summary>
/// 撤销命令
/// </summary>
/// <param name="levels">次数</param>
public void Undo(int levels)
{
for (int i = 1; i <= levels; i++)
{
if (undoCommands.Count != 0)
{
ICommand command = undoCommands.Pop();
isUndoing = true;
command.UnExecute();
redoCommands.Push(command);
isUndoing = false;
}
}
}
/// <summary>
/// 恢复撤销命令
/// </summary>
/// <param name="levels">次数</param>
public void Redo(int levels)
{
for (int i = 1; i <= levels; i++)
{
if (redoCommands.Count != 0)
{
ICommand command = redoCommands.Pop();
isRedoing = true;
command.Execute();
undoCommands.Push(command);
isRedoing = false;
}
}
}
/// <summary>
/// 插入命令
/// </summary>
/// <param name="command"></param>
public void InsertCommand(ICommand command)
{
undoCommands.Push(command);
redoCommands.Clear();
}
public void ClearAllCommand()
{
undoCommands.Clear();
redoCommands.Clear();
}
}
(2)AbsCommand:
public abstract class AbsCommand : ICommand
{
public abstract void Execute();
public abstract void UnExecute();
}
(3)子类实现ConcreteCommand1:
public class ConcreteCommand1 : AbsCommand
{
public override void Execute()
{
}
public override void UnExecute()
{
}
}
(4) CommandType:
public enum CommandType
{
DEFAULT,
ConfigAddCommand
}
3.UIEventArgs参数实现
(1)AbsUIEventArgs :
public abstract class AbsUIEventArgs : IEventArgs
{
public virtual Type type
{
get
{
return this.GetType();
}
protected set { }
}
public AbsUIEventArgs()
{
}
public abstract ushort HandlerName { get; }
}
(2)子类继承ConcreteUIEventArgs1 :
public class ConcreteUIEventArgs1 : AbsUIEventArgs
{
public override ushort HandlerName => ConcreteHandler1.Instance.HandleName;
}
4.Handler的实现:
(1)AbsHandler :
public abstract class AbsHandler : IHandler
{
public abstract ushort HandleName { get; protected set; }
private UIEventHandler _handler;
public AbsHandler()
{
_handler = UIEventHandler.Instance;
if (HandleName != 0)
{
_handler.Register(HandleName, this);
}
}
public virtual void Dispose(IEventArgs args)
{
}
public virtual void SendMessage(params object[] args)
{
_handler.SendMessage(HandleName, args);
}
}
(2)SimpleHandler:
public class SimpleHandler<T> : AbsHandler where T : new()
{
private static T _instance;
private static object _lock = new object();
public override ushort HandleName { get; protected set; }
protected SimpleHandler()
{
}
public static T Instance
{
get
{
if (_instance == null)
{
lock (_lock)
{
if (_instance == null)
{
_instance = new T();
}
}
}
return _instance;
}
}
}
(3)UIEventHandler (将UI事件分配给正确的处理Handler):
using System.Collections.Generic;
public class UIEventHandler : Singleton<UIEventHandler>
{
private Dictionary<ushort, IHandler> _handlersDic = new Dictionary<ushort, IHandler>();
private List<IUIEvent> _uiEventList = new List<IUIEvent>();
public void Register(ushort key, IHandler handler)
{
if (_handlersDic.ContainsKey(key))
{
return;
}
_handlersDic.Add(key, handler);
}
public void RegisterUI(IUIEvent ui)
{
if (ui != null && !_uiEventList.Contains(ui))
{
_uiEventList.Add(ui);
}
}
public void Dispose(IEventArgs eventArgs)
{
IHandler handler;
if (_handlersDic.TryGetValue(eventArgs.HandlerName, out handler))
{
handler.Dispose(eventArgs);
}
}
public void SendMessage(ushort sender, params object[] data)
{
if (sender != 0 && _handlersDic.ContainsKey(sender))
{
for (int i = 0; i < _uiEventList.Count; i++)
{
_uiEventList[i].Receive(sender, data);
}
}
}
}
(4)子类实现ConcreteHandler1 :
public class ConcreteHandler1 : SimpleHandler<ConfigStepHandler>
{
public override ushort HandleName => HandlerUtilities.ConcreteHandler1;
public override void Dispose(IEventArgs args)
{
}
}
(5)HandlerUtilities:
public class HandlerUtilities
{
public const ushort ConcreteHandler1 = 1;
}
5、事件面板注册实现
(1)AbsUIEvent :
public abstract class AbsUIEvent : IUIEvent
{
protected UIEventHandler eventHandler;
public AbsUIEvent()
{
eventHandler = UIEventHandler.Instance;
eventHandler.RegisterUI(this);
}
public virtual void SendEvent(IEventArgs args)
{
eventHandler.Dispose(args);
}
public virtual void Receive(ushort sender, params object[] data)
{
}
}
四、总结
框架说那么多不如自己去 直达下一篇(2) 实践一下!