Есть ли лучший вариант дизайна?

Отказ от ответственности:Я хотел бы использовать внедрение зависимостейна этом проект и имеют слабосвязанный дизайн на основе интерфейса по всем направлениям, но использование внедрения зависимостей в этом проекте было сбито. Кроме того, принципы проектирования 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 ();? Потенциальные обходные пути, о которых я думал, были бы следующими:

  1. У foo и helper есть двунаправленные отношения. Чтобы в DoSomethingHelpful мы могли вызвать foo.Operation2
  2. В foo реализовать интерфейс IHelp и переместить «вспомогательный» код в foo
  3. Использовать делегирование и передать метод Operation2 как Actionделегат в конструктор Helper.

Ни один из этих подходов не кажется идеальным (хотя я почти решил, что мне не нравится вариант 1и я беспокоюсь о ремонтопригодности с вариантом 3, если мы узнаем позже нам нужно передать больше делегатов). Это заставляет меня задаться вопросом, есть ли проблема с первоначальным дизайном комбинации Helper/ Foo. Мысли?

6
задан Matt 4 April 2012 в 15:13
поделиться