有更好的设计选择吗?

Mat*_*att 6 c# oop maintainability design-patterns

免责声明:我很乐意在这个项目中使用依赖注入,并且全面地采用基于接口的松散耦合设计,但是在这个项目中使用了依赖注入.另外,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");
    }
}
Run Code Online (Sandbox Code Playgroud)
// 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

说这两个类的用法如下:

    // 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();
Run Code Online (Sandbox Code Playgroud)

但是我现在发现我还需要foo.Operation1在某些实现中执行helper.DoSomethingHelpful();?我想到的潜在解决方法是:

  1. foo和helper有双向关系.所以在DoSomethingHelpful中我们可以调用foo.Operation2
  2. 让foo实现IHelp接口并将"helper"代码移动到foo中
  3. 使用委托并将方法Operation2作为Action<string>委托传递给Helper的构造函数.

这些方法似乎都不是理想的(虽然我几乎已经确定我不喜欢选项1,如果我们稍后发现我们需要传递更多的代表,我担心选项3的可维护性).这让我想知道Helper/ Foocombo 的初始设计是否存在问题.思考?

Dav*_*son 1

“这些方法似乎都不理想(尽管我非常确定我不喜欢选项 1,并且担心如果我们稍后发现需要传递更多代表,选项 3 的可维护性)。这让我想知道如果 Helper/Foo 组合的初始设计存在问题。”

你是完全正确的 - Helper 和 Foo 的设计存在问题。您最初描述的基本 Foo/Helper 关系很好,并且当您必须包装您无法控制的其他对象时,这是一种常见模式。但你接着说:

“如果我发现我还需要在 helper.DoSomethingHelpful(); 的某些实现中执行 foo.Operation1 怎么办?”

这就是我们遇到问题的地方。您一开始描述了 Foo 依赖于 Helper 的关系;现在您正在描述一种 Helper 依赖于 Foo 的关系。这立即告诉我你的依赖关系是混乱的。对象之间的依赖关系只能是一种方式;事实上依赖注入依赖于此。