-Поиск по дневнику

Поиск сообщений в eugene20237

 -Подписка по e-mail

 


Концептуальные проблемы ООП

Пятница, 10 Мая 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 = ...;
    ...........
  }
}


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

Вот такое наблюдение. Что с этим делать пока не знаю. Пойду ещё почитаю Фаулера.
Метки:  

Аноним   обратиться по имени Пятница, 10 Мая 2013 г. 14:09 (ссылка)
А в чем собственно проблема? Есть состояние, от него зависит поведение. Чтоб это уместилось в голове, надо аккуратно пользоваться инкапсуляцией и правильно называть методы. Это не совсем проблема ООП, тоже самое можно сказать про процедуры, или даже про функции, где вычисления сильно и не понятно зависят от значения аргументов. Возможно просто не правильно выбрана семантика внутреннего состояния.
Ответить С цитатой В цитатник    |    Не показывать комментарий
eugene20237   обратиться по имени Пятница, 10 Мая 2013 г. 15:10 (ссылка)
В первом случае очень легко сказать как работает метод "аdd". Т.е. как он изменит данные. Во втором случае представить себе работу метода "add" очень сложно и невозможно предугадать как он изменит данные. Теперь масштабируем проблему и представляем что таких параметров в классе много. Далее пробуем себе представить его поведение и описать словами "что он делает?". Потом добавляем в класс новую функциональность и понимаем что это уже опасно, потому что неизвестно как должен вести себя объект в текущем состоянии. Ну а дальше ошибки. На мой взгляд это проблема.
Ответить С цитатой В цитатник
Перейти к дневнику

Суббота, 11 Мая 2013 г. 08:50ссылка
Аноним
Согласен. Это проблема и она называется сложность, ООП тут не причем. Во первых надо сначала решить, что будет делать класс, а потом уже его создавать. Но если класс уже есть, то придется потратить время и разобраться, как он работает. Название класса и методов должно в этом помогать. Когда станет понятно, что класс делает, это знание надо отобразить в модульном тесте. Если для этого нужно немного порефакторить класс, это отлично, так как это улучшит архитектуру. Так-же нет ничего плохого в разносе функциональности по разным классам, если это упростит понимание.
Есть мнение, что если нет тестов, то система не работает. Это мнение как раз появилось из-за описанной тобой проблемы.
Перейти к дневнику

Суббота, 11 Мая 2013 г. 17:38ссылка
Я хочу понять как в принципе можно (и можно ли) отрефакторить такой класс. Например, как в последнем примере: где управлющее свойство используется и на чтение и на запись. Думаю, что можно было выделить новый класс и вынести в него один из методов, в котором либо читается, либо записывается управляющее поле. Но это долго. А быстрого решения я так и не нашёл, где, например, можно было бы не создавать такого свойства, которое в одном месте устанавливается, а в другом используется.
 

Добавить комментарий:
Текст комментария: смайлики

Проверка орфографии: (найти ошибки)

Прикрепить картинку:

 Переводить URL в ссылку
 Подписаться на комментарии
 Подписать картинку