Придерживаться ООП, имеющего список, содержащий объекты подтипов, и фильтровать его по типу - PullRequest
0 голосов
/ 01 октября 2019

Является ли хорошей практикой иметь список, содержащий объекты производных типов, а затем фильтровать его путем проверки типов, когда необходимо вызвать методы, специфичные для одного из типов? Из того, что я прочитал, проверка типов является некоторым запахом кода, и это указывает на то, что ООП используется не полностью.

Я использую общий список для объектов всех подтипов, потому что я хочу вызывать некоторые общие методы для всех объектов. Но некоторые методы специфичны для некоторых подтипов, и если я хочу вызвать метод, мне нужно отфильтровать объекты по типу.

public abstract class ParentType
{
  public abstract void CommonMethod();
}

public class DerivedTypeA : ParentType
{
  public override void CommonMethod()
  {
    //do something
  }

  public void TypeASpecificMethod()
  {
    //do something
  }
}

public class DerivedTypeB : ParentType
{
  public override void CommonMethod()
  {
    //do something
  }

  public void TypeBSpecificMethod()
  {
    //do something
  }
}

static void Main()
{
  List<ParentType> objects = new List<ParentType>()
  {
    new DerivedTypeA(),
    new DerivedTypeA(),
    new DerivedTypeB(),
    new DerivedTypeB()
  }

  //Call common method on all objects in a list
  foreach(var obj in objects)
  {
    obj.CommonMethod();
  }

  //Call only specific method for DerivedTypeA objects
  foreach(var obj in objects)
  {
    if(obj is DerivedTypeA derivedAObj) //type checking needed
    {
      derivedAObj.TypeASpecificMethod();
    }
  }
}

Ответы [ 4 ]

0 голосов
/ 01 октября 2019

Абсолютно никаких проблем, наоборот, вы все делаете правильно, используя ООП.

Сначала вы используете полиморфизм в одном из своих основных назначений для анализа списка объектов разных типов, имеющих одинаковый базовый тип, и вызываететот же метод.

Затем вы используете сопоставление типов, чтобы применить особый случай к неспецифическому списку объектов разных типов, имеющих один и тот же базовый тип, чтобы воздействовать только на те, которые являются определенным дочерним типом.

Это два элементарных примера.

Вы ничего не нарушаете.

Например, в реальном мире мойка автомобиля:

  • Одной и той же способом будет мыть внешнюю часть автомобилей разных типов: машины будут проходить одну за другой и применять один и тот же метод к каждой, это ваш первый цикл - он не имеет никакого отношения к типу автомобилей, поскольку ониавтомобили.

  • Тогда, скажем, его цель - наклеить ярлык только на автомобили с двумя дверьми, а не с четырьмя, это ваша вторая петля - он тзаботится о типе автомобиля, чтобы применить что-то только к определенному полу.

ООП существует, чтобы представлять реальность и использовать это представление наиболее естественным, простым, эффективным и надежным способомвозможно ... так что будь умным.

Следовательно, ты можешь написать это:

objects.OfType<DerivedTypeA>().ToList().ForEach(o => o.TypeASpecificMethod());

И ты будешь крепким.

0 голосов
/ 01 октября 2019

Давайте рассмотрим следующий код:

foreach (var obj in objects)
{
    if (obj is DerivedTypeA) 
    {
        obj.TypeASpecificMethod();
    }
}

По мере развития вашей логики вы, вероятно, получите что-то вроде этого:

foreach (var obj in objects)
{
    if (obj is DerivedTypeA) 
    {
        obj.TypeASpecificMethod();
    }
    else if (obj is DerivedTypeB)
    {
        obj.TypeBSpecificMethod();
    }
    else if (obj is DerivedTypeC)
    {
        obj.TypeCSpecificMethod();
    }
}

Приведенный выше код нарушает Открыто-закрыто принцип:

код должен быть открыт для расширения, но закрыт для модификации

Поскольку это гипотетический вопрос, трудно дать вамрешение ...

В сценарии реального мира вы можете взглянуть на Инверсия управления . Внедрение зависимостей и шаблон фабрики являются популярными формами IoC.

0 голосов
/ 01 октября 2019

Да, код, который вы предоставляете, нарушает принципы SOLID, вам следует избегать использования оператора if для проверки правильности типа. Вы можете использовать шаблон стратегии и фабрику, которая создает различные стратегии во время выполнения.

0 голосов
/ 01 октября 2019

Вы правы, это не ООП. Решение ООП состоит в том, чтобы реализация каждого типа CommonMethod вызывала другие конкретные методы, соответствующие типу.

...