我正在开发一个WinForm .Net应用程序,其基本用户界面包括工具栏按钮,菜单项和按键,它们都启动相同的底层代码。现在,每个事件的事件处理程序调用一个常用的方法来执行该功能。
根据我的阅读,Command design pattern可以处理这种类型的操作,还有自动启用/禁用或选中/取消选中UI元素的额外好处。
我一直在网上寻找一个很好的示例项目,但实际上还没有找到一个。有没有人有一个可以分享的好例子?
答案 0 :(得分:20)
让我们首先确保我们知道Command模式是什么:
命令模式封装了一个请求 作为一个对象并给它一个已知的 公共界面。命令模式 确保每个对象都接收它 拥有命令并提供解耦 发送者和接收者之间。发件人 是一个调用一个对象 操作,接收器是一个对象 接收请求并采取行动 它
这是给你的一个例子。有很多方法可以做到这一点,但我将采用一种基于接口的方法来使代码更易于测试。我不确定你喜欢哪种语言,但我是用C#写的。
首先,创建一个描述命令的界面。
public interface ICommand
{
void Execute();
}
其次,创建将实现命令接口的命令对象。
public class CutCommand : ICommand
{
public void Execute()
{
// Put code you like to execute when the CutCommand.Execute method is called.
}
}
第三,我们需要设置我们的调用者或发送者对象。
public class TextOperations
{
public void Invoke(ICommand command)
{
command.Execute();
}
}
第四,创建将使用调用者/发送者对象的客户端对象。
public class Client
{
static void Main()
{
TextOperations textOperations = new TextOperations();
textOperation.Invoke(new CutCommand());
}
}
我希望您可以使用此示例并将其用于您正在使用的应用程序。如果您想进一步澄清,请告诉我。
答案 1 :(得分:2)
你走在正确的轨道上。基本上你会有一个代表文档的模型。您将在CutCommand中使用此模型。您将需要更改CutCommand的构造函数以接受要剪切的信息。然后每次,单击剪切按钮,您调用一个新的CutCommand并在构造函数中传递参数。然后在调用Execute方法时在类中使用这些参数。
答案 2 :(得分:1)
尝试开源,.NET编辑器,如SharpDevelop或Notepad++。
({自然地] http://c2.com/cgi/wiki?CommandPattern对命令模式的一些讨论可能会有所帮助。
答案 3 :(得分:1)
Qt对菜单栏/工具栏项使用命令模式。
QActions是从QMenuItem和QToolbar单独创建的,并且可以分别使用setAction()和addAction()方法将Actions分配给QMenuItem和QToolbar。
http://web.archive.org/web/20100801023349/http://cartan.cas.suffolk.edu/oopdocbook/html/menus.html
http://web.archive.org/web/20100729211835/http://cartan.cas.suffolk.edu/oopdocbook/html/actions.html
答案 4 :(得分:0)
我无法通过示例链接为您提供帮助,但可以自己提供示例。
1)定义ICommand接口:
public abstract class WinFormCommand : ICommand {
}
2)对具体命令执行ICommand实现,还为它们定义抽象基类:
public interface ICommandInvoker {
void Invoke(ICommand command);
void ReDo();
void UnDo();
}
public interface ICommandDirector {
void Enable(ICommand);
void Disable(ICommand);
}
public class WinFormsCommandInvoker : ICommandInvoker, ICommandDirector {
private readonly Dictionary<ICommand, bool> _commands;
private readonly Queue<ICommand> _commandsQueue;
private readonly IButtonDirector _buttonDirector;
// you can define additional queue for support of ReDo operation
public WinFormsCommandInvoker(ICommandsBuilder builder, IButtonDirector buttonDirector) {
_commands = builder.Build();
_buttonDirector = buttonDirector;
_commandsQueue = new Queue<ICommand>();
}
public void Invoke(ICommand command) {
command.Do();
__commandsQueue.Enqueue(command);
}
public void ReDo() {
//you can implement this using additional queue
}
public void UnDo() {
var command = __commandsQueue.Dequeue();
command.Undo();
}
public void Enable(ICommand command) {
_commands.[command] = true;
_buttonDirector.Enable(command);
}
public void Disable(ICommand command) {
_commands.[command] = false;
_buttonDirector.Disable(command);
}
}
3)创建命令调用程序:
$validator = $this->validator->make($request->all(), $rules);
4)现在,您可以实现ICommandsBuilder,IButtonDirector并将其他接口(如ICheckBoxDirector)添加到WinFormsCommandInvoker。