Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Design Patterns via C#.pdf
Скачиваний:
153
Добавлен:
17.03.2016
Размер:
13.25 Mб
Скачать

186

Пример кода

Рассмотрим детальнее конкретные классы команд из раздела Мотивация. Класс OpenCommand, реализует команду открытия документа выбранного пользователем в приложении, используя метод AddDocument класса MainForm и реализуя абстрактный метод Execute родительского абстрактного класса

Command:

class OpenCommand : Command

{

public override void Execute()

{

var filename = AskUser();

if (!string.IsNullOrEmpty(filename))

{

var doc = new Document(); doc.Open(filename); LogExecution(" opened");

MainForm.MainFormInstance.AddDocument(doc);

}

else

{ LogExecution(" opening cancelled"); }

}

string AskUser()

{

LogExecution("Asking user."); var dlg = new OpenFileDialog();

dlg.InitialDirectory = Application.StartupPath; if (dlg.ShowDialog() == DialogResult.OK)

{

return dlg.FileName;

}

else

return string.Empty;

}

}

public partial class MainForm : Form

{

internal static Document CurrentDocument { get; set; }

internal static MainForm MainFormInstance { get; private set; }

public MainForm()

{

InitializeComponent(); toolStripMenuItem1.DropDownItems.AddRange(new ToolStripItem[] {

new MyMenuItem("Open",new OpenCommand()), new MyMenuItem("Close",new CloseCommand()), new ToolStripSeparator(),

new MyMenuItem("Cut",new CutCommand()), new MyMenuItem("Copy",new CopyCommand()),

new MyMenuItem("Paste",new PasteCommand()), new ToolStripSeparator(),

new MyMenuItem("MacroCopy",new MacroCommand(new OpenCommand(),

new SelectAllTextCommand(), new CopyCommand(),

new CloseCommand()))

});

MainFormInstance = this;

}

private void AddMenuItemWithTemplateCommands()

{

187

toolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem();

this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { toolStripMenuItem2});

toolStripMenuItem2.Name = "toolStripMenuItem2"; toolStripMenuItem2.Size = new System.Drawing.Size(106, 20); toolStripMenuItem2.Text = "DocumentTemplate Menu";

toolStripMenuItem2.DropDownItems.AddRange(new ToolStripItem[] {

new MyMenuItem("Cut",new SimpleCommand(CurrentDocument.Cut,"cut")),

new MyMenuItem("Copy",new SimpleCommand(CurrentDocument.Copy, "copy")), new MyMenuItem("Paste",new SimpleCommand(CurrentDocument.Paste,"paste")),

});

}

public void AddDocument(Document document)

{

document.MdiParent = this; document.Show();

AddMenuItemWithTemplateCommands();

}

public void Log(string logString)

{

logLabel.Text += Environment.NewLine + logString;

}

}

Классы CloseCommand, CopyCommand, CutCommand, PasteCommand, SelectAllTextCommand и MacroCommand аналогично реализуют соответственно закрытие документа, копирование и вырезание выделенного фрагмента текста, вставку текста из буфера обмена, выделение всего текстового содержимого в документе и заданную в коде приложения последовательность команд.

class CloseCommand : Command

{

public override void Execute()

{

if (MainForm.CurrentDocument != null)

{

LogExecution("close"); MainForm.CurrentDocument.Close();

}

}

}

class CopyCommand : Command

{

public override void Execute()

{

if (MainForm.CurrentDocument != null)

{

LogExecution("copy text: " + MainForm.CurrentDocument.DocumentContent.SelectedText); MainForm.CurrentDocument.Copy();

}

}

}

class CutCommand : Command

{

public override void Execute()

{

188

if (MainForm.CurrentDocument != null)

{

LogExecution("cut text: " + MainForm.CurrentDocument.DocumentContent.SelectedText); MainForm.CurrentDocument.Cut();

}

}

}

class PasteCommand : Command

{

public override void Execute()

{

if (MainForm.CurrentDocument != null)

{

LogExecution("paste text: " + Clipboard.GetText()); MainForm.CurrentDocument.Paste();

}

}

}

class SelectAllTextCommand : Command

{

public override void Execute()

{

if (MainForm.CurrentDocument != null)

{

LogExecution(MainForm.CurrentDocument.Text + "select all text"); MainForm.CurrentDocument.DocumentContent.SelectAll();

}

}

}

class MacroCommand : Command

{

public readonly List<Command> Commands = new List<Command>();

public MacroCommand(params Command[] commands)

{

Commands.AddRange(commands);

}

public override void Execute()

{

foreach (var c in Commands) c.Execute();

}

}

Заметим, что класс MacroCommand не содержит ссылок на объекты-исполнители запросов, т.к. они инкапсулированы в объектах типа Command, набор которых хранит в себе данный класс.

class SimpleCommand : Command

{

Action action; string actionKeyword;

public SimpleCommand(Action action, string actionKeyword)

189

{

this.action = action; this.actionKeyword = actionKeyword;

}

public override void Execute()

{

if (action != null)

{

LogExecution(actionKeyword + " text: " + MainForm.CurrentDocument.DocumentContent.SelectedText); action.Invoke();

}

}

}

В классе SimpleCommand каждая связка «объект-исполнитель – действие» задается делегатом типа Action при вызове конструктора класса, а объекты класса SimpleCommand оперируют только ссылкой на необходимый callback метод, который передан с делегатом класса Action.

Известные применения паттерна в .Net

System.Data.Odbc.OdbcCommand http://msdn.microsoft.com/ru-ru/library/system.data.odbc.odbccommand(v=vs.110).aspx

System.Data.OleDb.OleDbCommand http://msdn.microsoft.com/ru-ru/library/system.data.oledb.oledbcommand(v=vs.110).aspx

System.Data.OracleClient.OracleCommand http://msdn.microsoft.com/en-us/library/system.data.oracleclient.oraclecommand(v=vs.110).aspx

System.Data.SqlClient.SqlCommand http://msdn.microsoft.com/ru-ru/library/system.data.sqlclient.sqlcommand(v=vs.100).aspx

System.Windows.Input.ICommand http://msdn.microsoft.com/en-us/library/system.windows.input.icommand(v=vs.110).aspx

System.Windows.Input.ComponentCommands http://msdn.microsoft.com/ru-ru/library/system.windows.input.componentcommands(v=vs.110).aspx

System.Windows.Input.MediaCommands http://msdn.microsoft.com/ru-ru/library/system.windows.input.mediacommands(v=vs.110).aspx

System.Windows.Input.NavigationCommands http://msdn.microsoft.com/ru-ru/library/system.windows.input.navigationcommands(v=vs.110).aspx

System.Windows.Input.RoutedCommand http://msdn.microsoft.com/ru-ru/library/system.windows.input.routedcommand(v=vs.110).aspx

System.Windows.SystemCommands http://msdn.microsoft.com/ru-ru/library/system.windows.systemcommands(v=vs.110).aspx

System.Workflow.ComponentModel.Design.WorkflowMenuCommands http://msdn.microsoft.com/ruru/library/system.workflow.componentmodel.design.workflowmenucommands(v=vs.110).aspx

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]