• Авторизация


Концептуальные проблемы ООП 10-05-2013 00:35 к комментариям - к полной версии - понравилось!


Проблема в том, что поведение объекта может зависеть от его внутреннего состояния. Да, это проблема! Приведу парочку примеров на Java о том, что я имею в виду.

Вот пример хорошего класса, поведение которого относительно независимо от состояния объекта:


class Simple
{
  private int a = 0;

  public void add(int b)
  {
    a = a + b;
  }

  public int getA()
  {
    return a;
  }
}


Здесь метод "add" работает одинаково независимо от значения свойства "a". А вот пример похожего класса, где метод "add" ведёт себя более изощрённо, ориентируясь на значение "a".


class Difficult
{
  private int a = 0;

  public void add(int b)
  {
    if ((float)(a % 100) / 3 == (int)((a % 100) / 3) )
      a = a + b;
    else
      a = a - b;
  }

  public int getA()
  {
    return a;
  }
}


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

Вот другой пример на языке AS3:


class D
{
  var param1: boolean;
  var param2: boolean;

  function func1(...)
  {
    .........
      if (param2)
        param1 = abc;
      else
        param1 = xyz;
    .........
  }

  function func2(...)
  {
    .........
    if (param1 && asd)
      param2 = ...;
    ...........
  }
}


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

Вот такое наблюдение. Что с этим делать пока не знаю. Пойду ещё почитаю Фаулера.
вверх^ к полной версии понравилось! в evernote
Комментарии (4):
10-05-2013-14:09 удалить
А в чем собственно проблема? Есть состояние, от него зависит поведение. Чтоб это уместилось в голове, надо аккуратно пользоваться инкапсуляцией и правильно называть методы. Это не совсем проблема ООП, тоже самое можно сказать про процедуры, или даже про функции, где вычисления сильно и не понятно зависят от значения аргументов. Возможно просто не правильно выбрана семантика внутреннего состояния.
eugene20237 10-05-2013-15:10 удалить
В первом случае очень легко сказать как работает метод "аdd". Т.е. как он изменит данные. Во втором случае представить себе работу метода "add" очень сложно и невозможно предугадать как он изменит данные. Теперь масштабируем проблему и представляем что таких параметров в классе много. Далее пробуем себе представить его поведение и описать словами "что он делает?". Потом добавляем в класс новую функциональность и понимаем что это уже опасно, потому что неизвестно как должен вести себя объект в текущем состоянии. Ну а дальше ошибки. На мой взгляд это проблема.
11-05-2013-08:50 удалить
Ответ на комментарий eugene20237 # Согласен. Это проблема и она называется сложность, ООП тут не причем. Во первых надо сначала решить, что будет делать класс, а потом уже его создавать. Но если класс уже есть, то придется потратить время и разобраться, как он работает. Название класса и методов должно в этом помогать. Когда станет понятно, что класс делает, это знание надо отобразить в модульном тесте. Если для этого нужно немного порефакторить класс, это отлично, так как это улучшит архитектуру. Так-же нет ничего плохого в разносе функциональности по разным классам, если это упростит понимание.
Есть мнение, что если нет тестов, то система не работает. Это мнение как раз появилось из-за описанной тобой проблемы.
eugene20237 11-05-2013-17:38 удалить
Ответ на комментарий # Я хочу понять как в принципе можно (и можно ли) отрефакторить такой класс. Например, как в последнем примере: где управлющее свойство используется и на чтение и на запись. Думаю, что можно было выделить новый класс и вынести в него один из методов, в котором либо читается, либо записывается управляющее поле. Но это долго. А быстрого решения я так и не нашёл, где, например, можно было бы не создавать такого свойства, которое в одном месте устанавливается, а в другом используется.


Комментарии (4): вверх^

Вы сейчас не можете прокомментировать это сообщение.

Дневник Концептуальные проблемы ООП | eugene20237 - Дневник eugene20237 | Лента друзей eugene20237 / Полная версия Добавить в друзья Страницы: раньше»