Основы объектно-ориентированного проектирования

Небольшие классы


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

При систематическом ОО-подходе такие вопросы возникают всякий раз, когда приходится вводить классы, представляющие действия. Хотя некоторые ОО-языки дают возможность передавать программы как аргументы в другие программы, такое свойство противоречит базисной идее Метода - функции (программы) не существуют сами по себе, - они лишь часть некоторой абстракции данных. Поэтому вместо передачи операций следует передавать объект, поставляемый вместе с операцией, например, экземпляр COMMAND, поставляемый с операцией execute.

Иногда для операций приходится писать обертывающий класс, что кажется искусственным, особенно для людей, привыкших передавать процедуры в качестве аргументов. Но мне неоднократно приходилось видеть, что класс, введенный с единственной целью инкапсуляции операции, превращался позже в полноценную абстракцию данных с добавлением операций, о которых не шла речь в первоначальном замысле. Класс COMMAND не попадает в эту категорию, он с самого начала рассматривался как абстракция данных и имел два компонента (execute and undo). Но, что типично, серьезная работа с командами приводит к осознанию необходимости других компонентов, таких как:

  • argument: ANY - для представления аргументов команды (как это было сделано в одной из версий проекта);
  • help: STRING - для предоставления справки по каждой команде;
  • компоненты, поддерживающие протоколирование и статистику вызова команд.

Еще один пример взят из области численных вычислений. Рассмотрим классическую задачу вычисления интеграла. Как правило, подынтегральная функция f передается как аргумент в программу, вычисляющую интеграл. Традиционная техника представляет f как функцию, при ОО-проектировании мы обнаруживаем, что "Интегрируемая функция" является важной абстракцией со многими возможными свойствами. Для пришедших из мира C, Fortran и нисходящего проектирования необходимость написания класса в такой ситуации кажется простым программистским трюком. Возможно, первое время он неохотно будет принимать эту технику, смиряясь с ней. Продолжая проект, он скоро осознает, что интегрируемая функция - INTEGRABLE_FUNCTION - на самом деле является одной из главных абстракций проблемной области. В этом классе появятся новые полезные компоненты помимо компонента item (a: REAL): REAL, возвращающего значение функции в точке a.

То, что казалось лишь трюком, превращается в главную составляющую проекта.



Содержание раздела