sco*_*man 6 language-agnostic architecture design-patterns
所以我正在我正在这里工作的一个应用程序上实现类似svg编辑器的GUI.这些是其中需要的逻辑的一些示例:
等等.
我已经实现了所有这些项目,但我不喜欢最终结果,主要是因为我不得不使用大量标志来操作状态(鼠标点击&&左键&&不移动?这样做),当然这代码可以更优雅.所以我研究了一下,然后选择了这些选项:
管道模式:我将创建分别处理每个逻辑事件的类,并使用优先级顺序来提供首先要执行的操作/操作,以及事件如何传播到后续的管道项.
MVC:这是最常见的响应,但我现在如何使用它来使代码更干净对我来说非常模糊.
状态机:这很好但是管理状态机的粒度会很复杂
所以我要求SO大师提供有关如何构建更好,更快乐的代码的技巧.
我建议将UI输入映射的逻辑与特定操作分离为专用对象.让我们称它们为传感器对象.不知道你的实现语言,我会对此有所了解,但你应该明白这一点.
OperationSensor
+ OnKeyDown
+ OnKeyPress
+ OnKeyUp
+ OnLeftMouseDown
+ OnLeftMouseUp
+ OnNodeSelect
+ OnNodeDeselect
+ OnDragStart
+ OnDragStop
Run Code Online (Sandbox Code Playgroud)
假设您有一个聚合所有各种UI输入的中心类UiInputManager
.它使用特定于语言的机制来监听键盘和鼠标输入.它还检测基本操作,例如检测到鼠标是否被按下然后移动,这是逻辑"拖动".
UiInputManager
// event listeners
+ keyboard_keydownHandler
+ keyboard_keyupHandler
+ mouse_leftdownHandler
+ mouse_rightdownHandler
// active sensor list, can be added to or removed from
+ Sensors
Run Code Online (Sandbox Code Playgroud)
UiInputManager不负责了解这些输入导致的操作.它只是以语言特定的方式通知其传感器.
foreach sensor in Sensors
sensor.OnDragStarted
Run Code Online (Sandbox Code Playgroud)
或者,如果传感器侦听UiInputManager发出的逻辑事件
RaiseEvent DragStarted
Run Code Online (Sandbox Code Playgroud)
你现在拥有的是将输入路由到OperationSensor子类的管道.每个OperationSensor都具有与单个操作相关的逻辑.如果它检测到操作的条件已满足,则会创建相应的Command对象并将其传回.
// Ctrl + zooms in, Ctrl - zooms out
ZoomSensor : OperationSensor
override OnKeyDown
{
if keyDown.Char = '+' && keyDown.IsCtrlDepressed
base.IssueCommand(new ZoomCommand(changeZoomBy:=10)
elseif keyDown.Char = '-' && keyDown.IsCtrlDepressed
base.IssueCommand(new ZoomCommand(changeZoomBy:=-10)
}
Run Code Online (Sandbox Code Playgroud)
我建议命令对象从传感器传递到UiInputManager.然后管理员可以将它们传递到您的命令处理子系统.这使管理员有机会通知传感器操作已完成,允许他们在需要时重置其内部状态.
可以通过两种不同的方式处理多步操作.您可以在SensorOperation内部实现内部状态机,也可以使用"步骤1"传感器创建"步骤2"传感器并将其添加到活动传感器列表中,甚至可能从列表中删除自身.当"步骤2"完成时,它可以重新添加"步骤1"传感器并自行移除.
归档时间: |
|
查看次数: |
717 次 |
最近记录: |