Работа с иерархией наследования из-за принципа Open-Closed - PullRequest
0 голосов
/ 21 января 2019

Когда я пытаюсь следовать принципу Open-Closed (OCP) , после ряда реализованных вариантов использования я всегда получаю иерархию унаследованных классов. Обычно это происходит с ViewModel в структуре MVVM, потому что они сильно меняются. Например (C #, но может быть любой другой язык, ориентированный на классы):

internal class MyAwesomeViewModel
{
    private IDependency1 _dependency1;

    public string Property1 { get; set; }
    public ICommand Command1 { get; }

    public MyAwesomeViewModel(IDependency1 dependency1)
    {
        _dependency1 = dependency1;
        Command1 = new DelegateCommand(...);
    }
}

internal class MyAwesomeViewModelWithAnotherProperty: MyAwesomeViewModel
{
    public string Property2 { get; set; }

    public MyAwesomeViewModelWithAnotherProperty(IDependency1 dependency1)
        :base(dependency1)
    {
    }
}

internal class MyAwesomeViewModelWithNewCommandAndDependency: MyAwesomeViewModelWithAnotherProperty
{
    private IDependency2 _dependency2;

    public ICommand Command2;

    public MyAwesomeViewModelWithNewCommandAndDependency(IDependency1 dependency1, IDependency2 dependency2)
    : base(dependency1)
    {
        _dependency2 = dependency2;
        Command2 = new DelegateCommand(...);
    }
}

internal class MyAwesomeViewModelWithBunchNewProperties : MyAwesomeViewModelWithNewCommandAndDependency
{
    public int IntProperty { get; }
    public bool BoolProperty { get; }
    public double DoubleProperty { get; }

    public MyAwesomeViewModelWithBunchNewProperties(IDependency1 dependency1, IDependency2 dependency2)
    : base(dependency1, dependency2)
    {
    }
}

Проблема в том, что когда речь идет о глубине наследования 4 и более уровней, она становится очень грязной и трудной для чтения. Также я всегда сталкиваюсь с проблемой именования, которая является сигналом неправильной композиции (например, MainWindowViewModel , затем MainWindowViewModelCloseCommand , затем MainWindowViewModelUserRelatedProperties и т. Д.).

Поскольку используется только последний производный класс ( MyAwesomeViewModelWithBunchNewProperties в приведенном выше примере), иногда я рассматриваю вопрос о сжатии всего наследства перед выпуском или другой важной вехи в 1 классе, например:

internal class MyAwesomeViewModel
{
    public int IntProperty { get; }
    public bool BoolProperty { get; }
    public double DoubleProperty { get; }
    public string Property1 { get; set; }
    public string Property2 { get; set; }
    public ICommand Command1 { get; }
    public ICommand Command2;

    public MyAwesomeViewModelWithBunchNewProperties(IDependency1 dependency1, IDependency2 dependency2)
    {
        _dependency1 = dependency1;
        _dependency2 = dependency2;
        Command1 = new DelegateCommand(...);
        Command2 = new DelegateCommand(...);
    }
}

Но это может нарушить принцип единой ответственности (SRP) и привести к очень большому суперклассу.

Вопрос : Как решить проблему наследования? Или это совсем не проблема и нормально иметь такую ​​структуру классов?

Ответы [ 3 ]

0 голосов
/ 28 января 2019

Принципы SOLID - это идеи / рекомендации, которые помогут вам найти лучшие решения.* * * * * * * * * * * * * * *

Стратегия наследования, представленная здесь, не работает должным образом.Это ничего не дает и вызывает путаницу и больше работы.Это не очень хороший способ.

Но это может нарушить принцип единой ответственности (SRP) и привести к очень большому суперклассу.

SRP очень расплывчат вусловия того, что такое «единая ответственность».Вы можете определить это так узко или так широко, как вы хотите.Опять же, принцип заключается в том, чтобы направлять вас и заставлять думать о том, чтобы не смешивать вещи, которые должны быть разделены.

Здесь вы можете сказать: «Ответственность этого класса состоит в том, чтобы быть моделью для связывания данных.view. "

Суперкласс

То же самое.Это просто руководство.Вы никогда не можете сказать «класс может иметь не более N членов».Этот совет неверен для любого N, потому что N является контекстно-зависимым.

0 голосов
/ 30 января 2019

Состав по наследству!

Часто разработчики смотрят на принципы, подобные SOLID, и забывают о базовом принципе Композиция над наследованием.

Первое, что нужно запомнить, это то, что наследование тесно связывает вас с базовым классом. Это приводит к таким проблемам, как отказ в завещании (нарушение принципа подстановки Лискова).

Когда мы говорим о классах в ООП, мы определяем поведение, связанное с данными, а не объектами. Когда мы моделируем проблему с точки зрения поведения, которое она пытается достичь, мы можем получить небольшие строительные блоки.

Вы можете определить поведение ядра из MyAwesomeViewModel в крошечные классы, которые вы можете ссылаться на него в других ваших классах. Таким образом, вы можете легко составлять объекты, такие как MyAwesomeViewModelWithBunchNewProperties .

Что касается принципа единой ответственности, то это очень неправильно истолкованный принцип. SRP заявляет, что совместное поведение должно изменяться вместе. Это означает, что один набор поведений, которые зависят друг от друга и будут меняться вместе, принадлежат к одному классу.

Что касается вашего конкретного сценария, модели представлений часто могут не иметь преимуществ от композиции или наследования. Модели представления - это объекты передачи данных (DTO), они не фиксируют поведение. Дублирование кода здесь может быть очень легко пропущено \ приемлемо. Если дублирование кода создает проблему в ваших моделях представлений, просто составьте их из других DTO

0 голосов
/ 21 января 2019

Чтобы заставить OCP работать на вас, вы должны определить поведение, которое нужно вашим клиентам. Эти знания могут быть использованы для создания одного или нескольких интерфейсов, которые затем реализуют ваши классы ViewModel. Чтобы избежать иерархии наследования, вы могли бы предпочесть, чтобы композиция структурировала ваши ViewModels так, как

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