Это первый выпуск новой рубрики - "Секреты проектирования". Он посвящен рассказу о самой рубрике и затрагивает общие вопросы, связанные с созданием программ на языке Java. Кроме того, мы рассмотрим процесс разработки программ вообще и поговорим о тех разнообразных целях, без достижения которых вы не сможете правильно спроектировать программу.

Во время прошлогодней конференции JavaOne я участвовал в заседании, на котором докладчик говорил о планах Sun в отношении виртуальной машины Java (Java virtual machine, JVM). Он утверждал, что Sun планирует, среди прочего, решить все нынешние проблемы с производительностью своей виртуальной машины, в том числе ускорить синхронизацию методов и уменьшить влияние "сборки мусора" на производительность. В заключении он провозгласил цель Sun: усовершенствование JVM, которое позволило бы программистам не беспокоиться о возможных проблемах с виртуальной машиной при проектировании программ. В этом случае они смогут сосредоточиться на создании "добротных объектно-ориентированных проектов с многопоточной поддержкой".

Однако докладчик не уточнил, что же такое добротный объектно-ориентированный проект с многопоточной поддержкой. Этой проблеме и будет посвящена моя новая рубрика. В своих статьях я надеюсь ответить на вопрос: что такое добротный программный проект на языке Java и как его создавать?

Основные темы рубрики

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

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

  • Методы улучшения проектирования объектов
  • Создание иерархий классов
  • Зачем нужны интерфейсы?
  • Что такое полиморфизм?
  • Выбор между формированием и наследованием классов
  • Обеспечение многопоточной поддержки
  • Создание соответствий между потоками
  • Архитектура Model/Controller/View, используемая в классах JFC
  • Схемы проектирования

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

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

В этом месяце: Цели ясны, задачи определены

В этой, вводной статье рубрики "Секреты проектирования", я собираюсь, основываясь на собственном опыте, подробно рассказать о своей концепции проектирования программ. Кроме того, мы поговорим о процессе разработки программного обеспечения (ПО) и мне придется объяснить, что я понимаю под словом "проектирование".

Процесс разработки ПО

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

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

  • Спецификация
  • Проектирование
  • Реализация
  • Интеграция и тестирование

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

В своих статьях я буду обозначать термином "проектирование" ту стадию разработки, которая относится ко второму этапу приведенного выше плана. Для того, чтобы вы яснее поняли, что я имею в виду под каждым этапом, мне придется описать каждый из них в четырех последующих частях этой статьи.

Этап 1. Спецификация проблемной области

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

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

Когда все стороны собираются вместе, чтобы попытаться перенести на бумагу все требования, относящиеся к программному проекту, им необходимо в первую очередь изучить проблемную область. Сущность проблемной области состоит в описании конечного продукта на человеческом языке (а не на компьютерном). Представление того же конечного продукта на компьютерном языке относится уже к области решения. В ходе изучения проблемной области можно с самого начала выявить и обсудить множество неясных деталей, а также устранить имеющиеся противоречия.

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

Этап 2. Создание решения

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

  • Определение системы

    1) Разделение системы на отдельные программы (и ее документирование)
    2) Определение и документирование интерфейсов между отдельными программами
    3) Выбор библиотек независимых производителей и пакетов Java, которые будут использовать ваши Java-программы, и их документирование
    4) Выбор новых, созданных вами, библиотек (пакетов Java), которые будут совместно использовать различные компоненты вашей системы, и их документирование

  • Создание прототипов пользовательского интерфейса

    5) Создание прототипов пользовательского интерфейса для тех компонентов системы, которые имеют какой-нибудь пользовательский интерфейс

  • Объектно-ориентированное проектирование

    6) Проектирование и документирование иерархий классов
    7) Проектирование и документирование отдельных классов и интерфейсов

    Определение системы

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

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

    Создание прототипов пользовательского интерфейса

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

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

    Объектно-ориентированное проектирование

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

    1. Классы пользовательского интерфейса
    2. Классы проблемной области
    3. Классы управления данными

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

    Этап 3. Реализация

    Реализация - это программирование. Создание циклов, операторов захвата (catch clauses), переменных и комментариев, а также компиляция, тестирование элементов и устранение ошибок - вот что такое реализация. Это основная часть вашей работы.

    Этап 4. Интеграция и тестирование

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

    Документирование программных проектов

    Существует множество способов проектирования программ. Прежде всего, это общепринятые методики, направляющие вас в процессе трансформации проблемной области в область решения. При проектировании Java-программ вы можете воспользоваться одной из общепринятых методик, объединить несколько таких методик или отказаться от них вообще и заниматься проектированием по своему усмотрению. Но вне зависимости от того, как именно вы решили подступиться к стадии проектирования вашей программы, вам необходимо каким-нибудь образом задокументировать проект. Документирование не только поможет вам следить за ходом проектирования, но и позволит передавать проект на рассмотрение другим разработчикам. Благодаря этому вы сможете еще до начала реализации получить от своих коллег отклики и ценные советы по поводу проекта. Важно получить эти отклики еще на ранних этапах, пока его относительно легко видоизменить. На этапе проектирования скорректировать возможные ошибки в проекте гораздо легче, чем позднее, на этапах реализации, интеграции и тестирования. (Обратите внимание: процесс получения откликов на ваш проект и внесение соответствующих изменений в него, еще раз доказывает, что разработка программ - процесс итеративный).

    Во многих методиках проектирования для описания проекта предусмотрены графические обозначения. Инструменты компьютерного проектирования CASE (Сomputer Aided Software Engineering) в большинстве случаев позволяют документировать проект в процессе его подготовки. Однако при использовании Java у вас имеется и другая возможность. Язык Java позволяет без труда отобразить проект исключительно при помощи стандартных средств, являющихся частью любой среды разработки Java.

    Документирование проекта при помощи кода

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

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

    Кроме того вы будете обладать основой Java-кода для каждого созданного вами класса - полями, комментариями и методами с пустыми телами. (Это классы проблемной области и управления данными).

    Представление проекта с помощью javadoc

    Среда программирования Java включает инструмент javadoc, который поможет вам задокументировать проект и передать его другим разработчикам. Для Java существуют три вида комментариев:

    Одиночный - "//"
    Пара "/*" и "*/"
    Пара "/**" и "*/"

    Символ "//" показывает, что оставшаяся часть строки - это комментарий. Символы "/*" и "*/" указывают, что компилятор должен игнорировать все расположенные между ними символы. Символы "/**" и "*/" действуют аналогично, однако javadoc отбирает комментарии между "/**" и "*/" и помещает их в HTML-файл, который он формирует для документирования кода.

    Поэтому комментарии, которые начинаются с "/**", называются документационными комментариями или просто doc comments. javadoc анализирует файлы .java и формирует несколько HTML-файлов, которые описывают классы, поля, методы и демонстрируют документационные комментарии.

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

    Способность видоизменять код в ходе проектирования

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

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

    Пять надоедливых обезьян

    Жизнь такова, что при создании программ вам все время приходиться думать о целом ряде требований, которые нужно учитывать в процессе работы. Я называю их "обезьянами у вас на шее". Эти обезьяны постоянно спорят, потому что каждая из них старается обратить на себя ваше внимание, убедить вас, что ее проблема важнее всего. Первая здоровенная и тяжеленная обезьяна сидит у вас за спиной, обхватив вас за шею. Она то и дело вскрикивает: "Надо уложиться в срок!". Другая обезьяна взгромоздилась вам на макушку (потому что места на спине уже не осталось). Она колотит себя в грудь и вопит: "Главное - это правильно реализовать спецификацию!". Третья обезьяна подпрыгивает на компьютерном мониторе и пронзительно визжит: "Надежность! Надежность! Надежность!" Четвертая пытается вскарабкаться вам на ногу и горланит: "Не забудь о быстродействии!" Но это еще не все. Время от времени из-под клавиатуры осторожно выглядывает еще одна маленькая обезьянка. Когда это случается, все остальные обезьяны сейчас же замолкают. Тогда маленькая обезьянка медленно вылезает наружу, встает на задние лапки, и, глядя вам прямо в глаза, говорит: "Сделай так, чтобы твой код было легко читать и изменять". В этот момент остальные обезьяны с дикими криками набрасываются на маленькую обезьянку и заталкивают ее обратно под клавиатуру. После того, как она исчезает, остальные обезьяны возвращаются на свои места, и все начинается снова.

    Вы сидите в кабинете, работаете над программой и думаете, кого же из них слушать? Увы, в большинстве случаев слушать приходится всех. Если вы хотите, чтобы все получилось, то придется постараться. Нужно, чтобы все обезьяны остались довольны. Другими словами, нужно найти правильный баланс между всеми этими, подчас взаимоисключающими, требованиями.

    Первая обезьяна: как уложиться в срок?

    По собственному опыту могу сказать, что начальство будет довольно вашей работой только в том, случае, если вы не отстали от графика. В том, что выполнению работы в срок придается столь большое значение, нет ничего удивительного. Коммерческие программы разрабатываются для коммерческих целей. А бизнес есть бизнес.

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

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

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

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

    Вторая обезьяна: правильная реализация спецификации

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

    Третья обезьяна: надежность

    Если вы уложились в срок на промежуточных финишах (на этапах спецификации, проектирования и реализации), но для того, чтобы добиться достаточной надежности работы системы вам потребовалось два дополнительных года, у вас будут большие неприятности. Ошибки неизбежны, но существует определенный предел их количества. И если вы за него вышли, это означает, что продукт непригоден для использования, или по крайней мере менее конкурентоспособен. В зависимости от конкретного приложения этот предел может меняться. Согласитесь, что степень надежности программ навигации для пассажирских авиалайнеров должна быть большей, чем у обычного браузера. Однако определенный уровень надежности вы обязаны обеспечить в любом случае.

    Исходя из собственного опыта могу утверждать, что надежность обеспечивают две основные составляющие - хороший, основательный проект и правильное программирование. С появлением Java (характерными чертами которого являются новые возможности по сборке мусора и ограничения на указатели) обеспечить надежность программного продукта стало гораздо проще. Но даже при отсутствии проблем с памятью, появление недостаточно надежных программ все еще возможно. Они появляются именно в результате создания неудачного проекта и некачественного программирования.

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

    Четвертая обезьяна: быстродействие

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

    Пятая обезьяна: гибкость

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

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

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

    Заключение

    Что же такое "добротный объектно-ориентированный проект с многопоточной поддержкой"? Ответ на этот вопрос зависит от того, о чем именно идет речь - об объектной ориентации или о многопоточной поддержке.

    В первую очередь многопоточная поддержка связана с обеспечением надежности (вспомните третью обезьяну). Если вы забудете синхронизировать методы, которые действительно необходимо синхронизировать, это приведет к временному повреждению данных. Создание проектов с многопоточной поддержкой невозможно без понимания самого понятия "многопоточность", без ясного представления о требованиях к обеспечению поддержки многопоточности конкретных программ и без соответствующего программирования.

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

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

    Однако, прежде всего, создание добротного объектно-ориентированного проекта позволит обеспечить гибкость программы, то есть решит проблему, которая так беспокоит обезьяну номер пять. Добротный объектно-ориентированный проект позволит вам создать код, который можно без труда понять и изменить. А чем более гибким является тело кода, тем быстрее (и дешевле) процесс усовершенствования кода или исправления в нем ошибок.

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

    Примите участие в обсуждении

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

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

    Вы можете включиться в обсуждение, посылая свои сообщения на мой электронный адрес - bill.venners@javaworld.com.

    В следующем месяце

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


    Источники

  • На домашней странице Javadoc ( The Javadoc Home Page) вы найдете подробную информацию об этом инструменте документирования Java-кода
    http://www.javasoft.com/products/jdk/javadoc/index.html
  • Рекомендуемые книги по проектированию на Java
    http://www.artima.com/designtechniques/booklist.html
  • Часто задаваемые вопросы по объектно-ориентированному программированию
    http://www.cyberdyne-object-sys.com/oofaq/
  • 7237 совета по объектно-ориентированному программированию
    http://www.rhein-neckar.de/~cetus/software.html
  • Страница, посвященная объектно-ориентированному программированию
    http://www.well.com/user/ritchie/oo.html
  • Информация о видах объектной ориентации
    http://arkhp1.kek.jp:80/managers/computing/activities/
    OO_CollectInfor/OO_CollectInfo.html
  • Сравнение методов объектно-ориентированного анализа и проектирования
    http://www.iconcomp.com/papers/comp/comp_1.html
  • Методы объектно-ориентированного анализа и проектирования: сравнительный анализ
    http://wwwis.cs.utwente.nl:8080/dmrg/OODOC/oodoc/oo.html
  • Часто задаваемые вопросы по схемам проектирования
    http://gee.cs.oswego.edu/dl/pd-FAQ/pd-FAQ.html
  • Использование основных схем проектирования при работе с Java (Doug Lea)
    http://g.oswego.edu/dl/pats/ifc.html
  • Схемы Java AWT
    http://mordor.cs.hut.fi/tik-76.278/group6/awtpat.html
  • Схемы проектирования: Элементы многократно используемого объектно-ориентированного программного обеспечения на Java
    http://www.zeh.com/local/jfd/dp/design_patterns.html


    Билл Веннерс (Bill Venners) занимается профессиональным программированием уже 12 лет. Он работает в компании Artima Software. Его деятельность связана с консультациями и обучением программированию. В течении многих лет Веннерс разрабатывал ПО для нужд образования, а также для производителей бытовой электроники, полупроводников и для страховых компаний. Он занимался программированием на различных языках и на многих платформах: на языке ассемблера с различными микропроцессорами, на C под Unix, на C++ под Windows и на Java в Web. Он является автором книги "Виртуальная машина Java изнутри" ("Inside the Java Virtual Machine"). Его адрес электронной почты - bill.venners@javaworld.com.