У меня есть несколько интерфейсов, таких как:
public interface IFoo
{
void FooAction();
}
public interface IBar
{
void BarAction();
}
public interface IBiz
{
void BizAction();
}
...others...
Я также определил базовую абстрактную реализацию для моих интерфейсов.Примерно так:
public abstract class BaseFoo() : IFoo
{
void FooAction() { ... }
}
public abstract class BaseBar() : IBar
{
void BarAction() { ... }
}
public abstract class BaseBiz() : IBiz
{
void BizAction() { ... }
}
... others
Теперь мне нужно другое количество классов, которые реализуют подмножество этих интерфейсов.Например:
public class FooBar : IFoo, IBar
{
....
}
public class FooBiz : IFoo, IBiz
{
....
}
public class FooBarBiz : IFoo, IBar, IBiz
{
....
}
На языке, который поддерживает множественное наследование, я бы реализовал перечисленные выше классы, наследующие от нескольких абстрактных классов: Например:
public class FooBar : BaseFoo, BaseBar, IFoo, IBar
{
....
}
public class FooBiz : BaseFoo, BaseBiz IFoo, IBiz
{
....
}
public class FooBarBiz : BaseFoo, BaseBar, BaseBiz, IFoo, IBar, IBiz
{
....
}
, но это не разрешено в C #, посколькуэтот тип наследования не поддерживается.
Чтобы достичь того же результата, я думаю, что подход здесь состоит в том, чтобы использовать композицию вместо наследования и определять классы следующим образом:
public class FooBar : IFoo, IBar
{
private readonly BaseFoo Foo { get; set; } // not abstract now
private readonly BaseBar bar { get; set; } // not abstract now
FooBar(IFoo foo, IBar bar) // Dependency injected here
{
Foo = foo;
Bar = bar;
}
void FooAction()
{
Foo.FooAction();
}
void BarAction()
{
Bar.BarAction();
}
}
First ofвсе: этот шаблон правильный?Одна вещь, которая заставляет меня думать, что здесь что-то пахнет, это то, что композиция поверх наследования скрывает защищенные свойства и поля базовых классов.
Вместо композиции я мог бы также предоставить базовый абстрактный класс для каждой перестановки интерфейсов.Например.определить BaseFooBar, BaseFooBiz, BaseFooBarBiz, но и в этом случае я обнаружил, что слишком много работы и повторяющегося кода.
Какой правильный подход для такого рода проблем?