用作包含组件的接口的默认实现

发布于 2024-12-15 12:39:04 字数 363 浏览 2 评论 0原文

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

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

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

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

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

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

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

I have an interface IFoo for which I want to provide a default implementation Foo.
Foo can be used as a contained class/component by other classes that implement IFoo.

IFoo is used by several classes that mostly implement it by forwarding calls to Foo, but for some methods they may provide their own implementation.

Foo needs access to (private) members of the calling class.

Passing these members as arguments in method calls is not possible because they are not (and should not be) part of the IFoo interface.

Providing public properties to these members only for this purpose is unwanted because it would make the interfaces of the calling classes overly complex.

The question is: what is good design to give Foo access to these members or how is this normally achieved? Are there any known design patterns for this?

EDIT: inheritance is not an option because the classes that implement IFoo can't inherit from the same class.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

2024-12-22 12:39:04

你说没有继承?所以基本上你的 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);
     }
}

是否使感觉?如果没有,您将不得不提供更多信息。

伊泰,

No inheritance you say? So basically your Foo class doesn't need to implement IFoo, it just needs to make implementing IFoo easy. Why can't you add some parameters to the methods, then? Something like this:

OK, let's see. Let me make up some methods to make sure I got this right:

interface IFoo
{
    void DisplayTime();
}

And your FooImplHelper (made static just for the purpose of this example, I don't know if it makes sense in your case or not)

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

and the IFoo implementation

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

Does that make sense? If not, you're going to have to give some more information.

Itay,

提赋 2024-12-22 12:39:04

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

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# 支持类的多重继承而不仅仅是接口,但遗憾的是事实并非如此。

There is no reason to declare the implementation method signature the same as interface method signature, so you should be able to freely pass the arguments around. For example:

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;
}

Alternatively, you could just memorize private objects in the implementation class and use composition:

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;
}

Of course, the ideal solution would be if C# supported multiple inheritance for classes and not just interfaces, but this is sadly not the case.

拿命拼未来 2024-12-22 12:39:04

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

定义第二个接口:

 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 接口。不过,我真的不认为他们中的任何一个人会喜欢额外的工作……

Itay。

Another possibility, because you asked for one. I prefer the first one, though.

Define a second interface:

 interface IFooImplHelper
 {
      int UTFOffset { get; }
 }

and make your FooImpl class look like this:

 class FooImpl: IFoo
 {
      private IFooImplHelper _helper;

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

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

Your clients will need to implement both the IFoo interface (Forwarding calls to FooImpl) and the IFooImplHelper interface. I really don't think any of them would appreciate the extra work, though...

Itay.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文