Рассмотрим следующий элемент управления (сокращенный для краткости):
public partial class ConfigurationManagerControl : UserControl
{
public Func<string, bool> CanEdit { get; set;}
public Func<string, bool> CanDelete { get; set; }
public Dictionary<string, string> Settings
{
get { return InnerSettings; }
set
{
InnerSettings = value;
BindData();
}
}
private Dictionary<string, string> InnerSettings;
private void OnListIndexChanged(object sender, EventArgs e)
{
this.EditButton.Enabled = false;
this.DeleteButton.Enabled = false;
var indices = this.List.SelectedIndices;
if (indices.Count != 1)
{
return;
}
var index = indices[0];
var item = this.List.Items[index];
if (this.CanEdit != null)
{
this.EditButton.Enabled = this.CanEdit(item.Text);
}
if (this.CanDelete != null)
{
this.DeleteButton.Enabled = this.CanDelete(item.Text);
}
}
}
Там больше для этого элемента управления, но достаточно сказать, что он позволяет пользователю добавлять, редактировать и удалять записи в словаре < string, string > . Чтобы определить, разрешить ли пользователю редактировать или удалять записи, он использует свойства метода делегата CanDelete и CanEdit, которые предоставляются формой или элементом управления, который его размещает:
public class SetupWizard : Form
{
public SetupWizard()
{
InitializeComponent();
this.SettingManager.CanEdit = CanEditSetting;
this.SettingManager.CanDelete = CanDeleteSetting;
}
private static bool CanEditSetting(string item)
{
var lockedSettings = new[] { "LicenseHash", "ProductHash" };
return !lockedSettings.Contains(item.ToLower());
}
private static bool CanDeleteSetting(string item)
{
var lockedSettings = new[] {
"LicenseHash",
"ProductHash",
"UserName",
"CompanyName"
};
return !lockedSettings.Contains(item.ToLower());
}
}
Я считаю, что этот дизайн одновременно является удовлетворительным и тревожным. С одной стороны, это, по-видимому, решает проблему, используя простейшее решение, которое работает (это, безусловно, отлично разделяет проблемы). С другой стороны, у меня есть это подозрительное беспокойство, что я неправильно использую делегатов и вместо этого должен использовать событие (даже если мне не нужны несколько слушателей, и мне нужен только вызывающий, чтобы сообщить мне, доступен ли элемент для редактирования).
И затем, с другой стороны, есть вероятность, что есть совершенно другой дизайн, который я даже не рассматривал, который мог бы решить проблему значительно превосходящим образом.
Итак. Является ли эта конструкция технически правильной, удобной и гибкой? Или я должен делать что-то лучше?