Отказ от ответственности:Я хотел бы использовать внедрение зависимостейна этом проект и имеют слабосвязанный дизайн на основе интерфейса по всем направлениям, но использование внедрения зависимостей в этом проекте было сбито. Кроме того, принципы проектирования SOLID(и шаблоны проектированияв целом) являются чем-то чуждым там, где я работаю, и я сам плохо знаком со многими из них. Так что прими это в внимание при предложении лучшего дизайна для этой проблемы.
Вот упрощенная версия кода, над которым я работаю, и поэтому он может показаться надуманным. Если это так, я извиняюсь.Рассмотрим следующие классы:
// Foo is a class that wraps underlying functionality from another // assembly to create a simplified API. Think of this as a service layer class, // a facade-like wrapper. It contains a helper class that is specific to // foo. Other AbstractFoo implementations have their own helpers. public class Foo : AbstractFoo { private readonly DefaultHelper helper; public override DefaultHelper Helper { get { return helper; } } public Foo() { helper = new Helper("custom stuff"); } public override void Operation1(string value) { Console.WriteLine("Operation1 using " + value); } public override void Operation2() { Console.WriteLine("Operation2"); } }
// Helper derives from a default implementation and allows us to // override it's methods to do things specific for the class that // holds this helper. Sometimes we use a custom helper, sometimes // we use the default one. public class Helper : DefaultHelper { private readonly string customStuff; public Helper(string value) { customStuff = value; } public override void DoSomethingHelpful() { Console.WriteLine("I was helpful using " + customStuff); } }
Скажем, эти два класса используются следующим образом:
// foo referenced and used in one part of code var foo = new Foo(); foo.Operation2(); // or foo.Operation1(); // some other point in the program where we don't have a reference to foo // but do have a reference to the helper helper.DoSomethingHelpful();
Однако теперь я обнаружил, что мне также нужно выполнить
foo.Operation1
в некоторых реализацияхhelper.DoSomethingHelpful ();
? Потенциальные обходные пути, о которых я думал, были бы следующими:
- У foo и helper есть двунаправленные отношения. Чтобы в DoSomethingHelpful мы могли вызвать foo.Operation2
- В foo реализовать интерфейс IHelp и переместить «вспомогательный» код в foo
- Использовать делегирование и передать метод Operation2 как
Action
делегат в конструктор Helper.Ни один из этих подходов не кажется идеальным (хотя я почти решил, что мне не нравится вариант 1и я беспокоюсь о ремонтопригодности с вариантом 3, если мы узнаем позже нам нужно передать больше делегатов). Это заставляет меня задаться вопросом, есть ли проблема с первоначальным дизайном комбинации
Helper
/Foo
. Мысли?