0

我有一个接口 IFoo,我想为其提供一个默认实现 Foo。Foo 可以被其他实现 IFoo 的类用作包含的类/组件。

IFoo 被几个类使用,这些类主要通过转发对 Foo 的调用来实现它,但对于某些方法,它们可能会提供自己的实现。

Foo 需要访问调用类的(私有)成员。

在方法调用中将这些成员作为参数传递是不可能的,因为它们不是(也不应该是) IFoo 接口的一部分。

仅出于此目的向这些成员提供公共属性是不受欢迎的,因为这会使调用类的接口过于复杂。

问题是:让 Foo 访问这些成员的良好设计是什么,或者这通常是如何实现的?是否有任何已知的设计模式?

编辑:继承不是一个选项,因为实现 IFoo 的类不能从同一个类继承。

4

3 回答 3

1

没有理由将实现方法签名声明为与接口方法签名相同,因此您应该能够自由地传递参数。例如:

interface IFoo {
    void MyMethod();
}

static class FooImp {
    public static void MyMethodImp(object private_object) {
        // ...
    }
}

class MyFoo : IFoo {
    public void MyMethod() {
        FooImp.MyMethodImp(m_PrivateObject);
    }
    object m_PrivateObject;
}

或者,您可以只记住实现类中的私有对象并使用组合:

interface IFoo {
    void MyMethod();
}

static class FooImp {
    public FooImp(object private_object) {
        m_PrivateObject = private_object;
    }
    public void MyMethodImp() {
        // Use the m_PrivateObject somehow.
    }
    readonly object m_PrivateObject;
}

class MyFoo : IFoo {
    public MyFoo() {
        m_PrivateObject = ... ;
        m_FooImp = new FooImp(m_PrivateObject);
    }
    public void MyMethod() {
        m_FooImp.MyMethodImp();
    }
    object m_PrivateObject;
    readonly FooImp m_FooImp;
}

当然,理想的解决方案是如果 C# 支持类的多重继承,而不仅仅是接口,但遗憾的是事实并非如此。

于 2011-11-14T13:10:49.663 回答
1

你说没有继承?所以基本上你的 Foo 类不需要实现 IFoo,它只需要使实现 IFoo 变得容易。那为什么不能在方法中添加一些参数呢?像这样的东西:

好吧,让我们来看看。让我编出一些方法来确保我做对了:

interface IFoo
{
    void DisplayTime();
}

还有您的 FooImplHelper (仅出于本示例的目的而设为静态,我不知道在您的情况下是否有意义)

public static FooImplHelper
{
    public static void DisplayTime(int UTFOffiset)
    {
        Console.WriteLine(DateTime.UtcNow + TimeSpan.FromHours(UTFOffset));
    }
}

和 IFoo 实现

public class MyClock: BaseClock, IFoo
{
     public void DisplayTime()
     {
         FooImplHelper.DisplayTime(2);
     }
}

那有意义吗?如果没有,您将不得不提供更多信息。

伊泰,

于 2011-11-14T11:05:56.057 回答
0

另一种可能性,因为你要了一个。不过我更喜欢第一个。

定义第二个接口:

 interface IFooImplHelper
 {
      int UTFOffset { get; }
 }

并使您的 FooImpl 类看起来像这样:

 class FooImpl: IFoo
 {
      private IFooImplHelper _helper;

      public FooImpl(IFooImplHelper helper)
      {
           _helper = helper;
      }

      public void DisplayTime()
      {
            Console.WriteLine(DateTime.UtcNow + TimeSpan.FromHours(_helper.UTFDifference);
      }
 }

您的客户端将需要实现 IFoo 接口(转发对 FooImpl 的调用)和 IFooImplHelper 接口。我真的不认为他们中的任何人会欣赏额外的工作,虽然......

伊泰。

于 2011-11-14T12:08:05.747 回答