Состав за пределы наследования - PullRequest
0 голосов
/ 04 июня 2018

У меня есть несколько интерфейсов, таких как:

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, но и в этом случае я обнаружил, что слишком много работы и повторяющегося кода.

Какой правильный подход для такого рода проблем?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...