Comments 12
Следующий после вас разработчик будет очень грустно перебирать form.Item1...Item42 в поисках IYetAnotherButtonPropertyInterface.
Согласен. Но как по-другому?
Переносить логику раскраски в формы. Передавать из контроллера (презентера) только данные/состояние. Делать разделение интерфейсов на уровне форм, если с одной формой действительно работает несколько контроллеров. Не открывать наружу элементы в виде свойств. Делать у формы (вида) методы HighlightWelcomeButton, SetWelcomeText и событие WelcomeClicked. У вас практически Model-View-Presenter, но с нарушением инкапсуляции вида. А нарушение инкапсуляции приводит к высокой связности, которую вы как раз пытаетесь побороть.
Ваше решение, как минимум, оригинально :) Хотя обращения через .Item1, .Item2 и т.п. выглядят некрасиво. Использовать такое тоже достаточно неинтуитивно.
Пришло на ум еще вот такое решение:
Ну, а вообще, я согласен с первым комментатором. Такие извороты обычно говорят об ошибке проектирования. Я бы, все же, постарался обойтись проектированием через интерфейсы и выделению для каждого конкретного случая нужного интерфейса.
Пришло на ум еще вот такое решение:
class BaseButton { }
interface IClickable { event Action Click; }
interface IColored { Color Color { get; set; } }
interface ITextContaining { string Text { get; set; } }
class CoolButton : BaseButton, IClickable, IColored, ITextContaining
{
// реализует все интерфейсы
}
class MyForm
{
private BaseButton button;
public BaseButton Button
{
get { return button; }
set
{
if(!(value is IColored || !(value is IClickable)))
{
throw new ArgumentException("Button object must be clickable and colored");
}
button = value;
}
}
public Action ButtonClick
{
get
{
return (button as IClickable).Click;
}
}
// [...]
}
Ну, а вообще, я согласен с первым комментатором. Такие извороты обычно говорят об ошибке проектирования. Я бы, все же, постарался обойтись проектированием через интерфейсы и выделению для каждого конкретного случая нужного интерфейса.
Скажите, а пример с кнопкой — это реальный пример? Потому что в нем явно можно обойтись нормальным наследованием — например:
Да и вообще, где вы видели столько разных контролов — и кнопка текстовая, и цветная, и цветная текстовая некликабельная, и цветная текстовая кликабельная, и еще 10 штук других сочетаний… Обычно ведь этих кнопок 2-3 разных вида. И в классах-формах можно использовать именно эти 2-3 конкретных класса.
У вас есть какой-нибудь другой пример, где это может понадобиться?
class BaseButton : IClickable { ... }
class ColorButton: BaseButton, IColored { ... }
class TextColoredButton ...
Да и вообще, где вы видели столько разных контролов — и кнопка текстовая, и цветная, и цветная текстовая некликабельная, и цветная текстовая кликабельная, и еще 10 штук других сочетаний… Обычно ведь этих кнопок 2-3 разных вида. И в классах-формах можно использовать именно эти 2-3 конкретных класса.
У вас есть какой-нибудь другой пример, где это может понадобиться?
Про кнопку — это просто пример. У меня была такая ситуация в коде с сервисами и провайдерами данных — они содержали кучу свойств/методов, и я их пытался расчленять на более простые. Напрмер, был провайдер SQL-БД, который имел сотни методов для доступа к разным таблицам — пришлось выделить интерфейсы для работы с разными сущностями (каждый интерфейс содержал десятки методов, получилось несколько таких интерфейсов). Но потом мне пришлось передавать эти интерфейсы в слой бизнес логики путем их перечисления, а это как-то не очень красиво.
Sign up to leave a comment.
C# — «Множественное наследование» в свойстве класса (или параметре функции)