问题
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.
回答1:
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,
回答2:
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.
回答3:
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.
来源:https://stackoverflow.com/questions/8120627/default-implementation-of-an-interface-that-is-used-as-a-contained-component