Suppose that I have a base interface, IBase
, that describes some minimal behavior that I care about. Additionally, there are some specific functionality interfaces, IFunctionalityA
and IFunctionalityB
, that provide some specialized algorithms. Also, I have some actor, Actor
, that performs some operation on IBase
objects. Finally, I want to wrap an IBase
in a class that keeps the same interface implementations. Is there a good pattern/code structure to help me do this?
The Desired Effect
Here's the setup:
interface IBase {}
interface IFunctionalityA : IBase
{
int DoSomethingA();
}
interface IFunctionalityB : IBase
{
int DoSomethingB();
}
// This class is the main implementation problem.
class Wrapper
{
IBase wrapped;
Wrapper(IBase obj) { wrapped = obj }
}
class Actor
{
void Act(IBase obj)
{
int result;
if (obj is IFunctionalityA objA)
result = objA.DoSomethingA();
if (obj is IFunctionalityB objB)
result = objB.DoSomethingB();
}
}
Then, if you created a wrapper with an IFunctionalityA
object,
IFunctionalityA objA;
var wrapper = new Wrapper(objA);
the wrapper would act like it implemented IFunctionalityA
// ACTS LIKE
class Wrapper : IFunctionalityA
{
IFunctionalityA wrapped;
int DoSomethingA() => wrapper.DoSomethingA();
}
and similarly
IFunctionalityB objB;
var wrapper = new Wrapper(objB);
would act like it implemented IFunctionalityB
// ACTS LIKE
class Wrapper : IFunctionalityB
{
IFunctionalityB wrapped;
int DoSomethingB() => wrapper.DoSomethingB();
}
Obviously the code can't work exactly like this. I'm looking for a pattern that helps me achieve the same effect.
Restrictions
- I can't use generics in the obvious way. I can't just have
because I just have a collection ofclass Wrapper<T> where T : IBase { /*...*/ }
IBase
objects. - I can't use a property like so
because I'd lose a lot of flexibility that I gain from inheritance in the first place and I have many functionality interfaces.class Wrapper { IBase wrapped; bool ImplementFunctionalityA => wrapped is IFunctionalityA; bool ImplementFunctionalityB => wrapped is IFunctionalityB; }
Possible Solution
I could try to implement a service provider-style design.
interface IBase
{
T GetFunctionality<T>() where T : IFunctionality;
}
interface IFunctionality { }
interface IFunctionalityA : IFunctionality { int DoSomethingA() { /*...*/ }
interface IFunctionalityB : IFunctionality { int DoSomethingB() { /*...*/ }
class Wrapper : IBase
{
IBase wrapped;
T GetFunctionality<T>() where T : IFunctionality
{
return wrapped.GetFunctionality<T>();
}
}
This seems like it would work fine but it seems like it might fragment the connection between the base behavior and specific functionalities. Perhaps that's okay or even better. I'm not sure but any suggestions for patterns, principles, or design would be greatly appreciated. Thanks!
Aucun commentaire:
Enregistrer un commentaire