Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

СПО_1 / СПО / Sozdanie.setevyh.prilojenii.v.srede.Linux

.pdf
Скачиваний:
80
Добавлен:
11.04.2015
Размер:
2.94 Mб
Скачать

Случай №9.1: "Отправка сообщения: в приеме сообщения отказано"

[Пользователь вводит сообщение и щелкает на кнопке Send] Устанавливаем соединение с удаленным узлом Вызываем абонента [Абонент отказывается принять сообщение]

Сообщаем пользователю об отказе [Пользователь получает код завершения]

Случай№9.2:"Отправкадлинногосообщенияпользователюсети"

[Пользователь вводит сообщение и щелкает на кнопке Send] Устанавливаем соединение с удаленным узлом Вызываем абонента [Абонент подтверждает наличие связи]

Отправляем сообщение по частям Выдаем подтверждение пользователю [Пользователь получает код завершения]

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

Именование объектов

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

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

Разграничение этапов анализа и проектирова

ния

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

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

На этапе анализа предметную область нужно рассматривать на макроуровне. Если кто то упоминает конкретную деталь реализации, она должна быть отнесена к этапу проектирования.

Глава 14. Ограничения объектно ориентированного...

281

Ⱦɚɧɧɚɹ ɜɟɪɫɢɹ ɤɧɢɝɢ ɜɵɩɭɳɟɧɚ ɷɥɟɤɬɪɨɧɧɵɦ ɢɡɞɚɬɟɥɶɫɬɜɨɦ %RRNV VKRS Ɋɚɫɩɪɨɫɬɪɚɧɟɧɢɟ ɩɪɨɞɚɠɚ ɩɟɪɟɡɚɩɢɫɶ ɞɚɧɧɨɣ ɤɧɢɝɢ ɢɥɢ ɟɟ ɱɚɫɬɟɣ ɁȺɉɊȿɓȿɇɕ Ɉ ɜɫɟɯ ɧɚɪɭɲɟɧɢɹɯ ɩɪɨɫɶɛɚ ɫɨɨɛɳɚɬɶ ɩɨ ɚɞɪɟɫɭ piracy@books-shop.com

Системныеограничения

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

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

Правильный уровень детализации

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

Избыточное наследование

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

Вбольшинстве случаев достаточно построить естественную иерархию классов

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

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

Неправильное повторное использование

Распространенный миф, прпулярный среди поклонников объектно ориентированного программирования, гласит, что любой компонент можно ис пользовать многократно. Это очень "абстрактная" вера. Многие классы наилуч шим образом используются именно там, где они изначально проектировались.

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

282

Часть III. Объектно ориентированные сокеты

www.books-shop.com

Соответствует ли основное назначение класса поставленной задаче?

Достаточно ли переписать всего один или два метода?

Правильную ли роль играют родительские классы?

Правильно ли обрабатываются существующие данные?

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

Правильное применение спецификатора friend

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

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

Перегруженные операторы

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

Не передавайте данные по значению или через указатель — вместо этого везде, где возможно, применяйте ссылки (s). В противном случае могут возникнуть потерянные указатели или же произойдет снижение произ водительности из за постоянного вызова конструкторов и деструкторов.

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

Выбирайте оператор, соответствующий смыслу операции, — например, запись <строка>+<строка> понятна, а запись *<стек> не обязательно

означает выражение <стек> >Рор{).

При необходимости делайте перегруженными операторы new и delete — некоторые авторы рекомендуют делать это всегда, хотя это спорный во прос.

Никогда не перегружайте непонятные операторы — перегруженные опе раторы вызова функции ("()") и доступа к полям структур ("." и " >")

редко будут использоваться правильно.

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

Глава 14. Ограничения объектно ориентированного...

283

www.books-shop.com

Объекты не решают всех проблем

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

И снова об избыточном наследовании

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

Недоступный код

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

Неполные классы

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

Пустые методы

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

Мутации объектов

Еще один недостаток заключается в мутации объектов, когда один объект мо жет быть преобразован в другой без операции приведения типа. Даже в объектно ориентированных языках программирования со строгой типизацией, таких как C++ и Java, эта операция потенциально опасна. Мутация — это форма преобра зования, при которой объект переходит из одного состояния в другое по опреде ленным правилам. Сначала создается общий объект, который по мере анализа

284

Часть III. Объектно ориентированные сокеты

www.books-shop.com

постепенно раскрывает свои свойства, в результате чего может даже получиться совершенно новый, ранее неизвестный в программе класс. Мутация широко применяется при работе с объектными потоками, где имеется большой двоичный объект (BLOB — binary large object), который нужно "расшифровать". Например, можно создать конструктор трансляции, который в зависимости от внутренней структуры полученного аргумента создает объект того или иного класса.

Мутация выполняется при соблюдении следующих условий.

Большой двоичный объект должен оставаться цельным — модуль преобра зования не должен копировать объект или менять его структуру. Должен меняться лишь способ интерпретации объекта.

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

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

В результате всегда должен получаться экземпляр конкретного класса

причина этого понятна: не должен существовать объект неполного класса.

Модуль преобразования должен иметь доступ к закрытым членам класса —

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

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

Мутировавшие объекты — это отличное средство работы с классами, о кото рых на этапе создания программы еще не было известно.

Проблема чрезмерной сложности

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

Игнорирование устоявшихся интерфейсов

За время существования объектно ориентированного программирования про фессионалы усвоили ряд уроков. Основной из них — важность устоявшихся ин терфейсов. Интерфейс класса определяет его долговечность. Но у программистов редко хватает времени на разработку наилучшего интерфейса.

Как правило, интерфейсы получаются слишком специализированными или функционально перенасыщенными. Часто встречается такой подход: "Этот метод здесь полезен — почему бы не реализовать его еще здесь и вот здесь?" Интерфейс должен оставаться простым и интуитивно понятным.

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

Глава 14. Ограничения объектно ориентированного...

285

www.books-shop.com

Множественное наследование

Сложность возникает вследствие увлечения наследованием. В C++ можно создавать классы, являющиеся потомками сразу нескольких классов. Управлять такой иерархией достаточно сложно. В главе 11, "Экономия времени за счет объ ектов", вводилось понятие связности модулей. Когда применяется множествен ное наследование, возникает чрезмерная связность между классами. В случае из менения родительских классов разработчику часто приходится проверять интер фейс дочернего класса, что неудобно.

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

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

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

Разрастание кода

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

В зависимости от сложности классов ;их размер может на 20—50% превышать размер функциональных аналогов, написанных средствами модульного програм мирования. В основном это связано с усложнением синтаксиса. Однако эта жерт ва оправдана: несмотря на повышение сложности программы увеличиваются ее возможности и усиливается контроль над типами данных.

Впервые столкнувшись с объектами, программисты были удивлены разраста нием кода. В некоторых случаях размер программы, написанной по объектной технологии на C++, на порядок превышал размер аналогичной модульной С программы. Это, конечно, крайность, но вполне можно ожидать двух или пяти кратного увеличения программы.

Можно избежать разрастания, придерживаясь следующих правил.

Старайтесь не перегружать операторы без особой необходимости.

Не пытайтесь втиснуть все классы в рамки единой иерархии наследова ния.

Не применяйте виртуальное наследование.

Поменьше используйте виртуальные методы.

Старайтесь избегать множественного наследования.

286

Часть III. Объектно ориентированные сокеты

www.books-shop.com

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

Проблема управления проектами

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

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

Нужные люди в нужное время

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

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

Спонсор проекта — выделяет деньги на его реализацию и определяет ос новные направления проекта.

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

продукту, и оказывает консультации по ходу выполнения проекта.

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

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

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

тролю начнет разрабатывать тесты, на основании которых будет осуществ

Глава 14. Ограничения объектно ориентированного...

287

www.books-shop.com

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

Программисты — осуществляют проектирование системы и программи руют ее на выбранном языке.

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

Между двух огней

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

Как свидетельствует мировой опыт, лишь 20% времени проекта уходит непо средственно на программирование. Остальные 80% поровну распределяются меж ду этапами анализа/проектирования и тестирования. В американской программ ной индустрии показатели обычно такие: 33% — анализ и проектирование, 34% — программирование и 33% — тестирование. Итого программирование за нимает в лучшем случае 34% времени. Так почему бы не тратить спокойно время на анализ исходных требований и проектирование?

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

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

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

Тестирование системы

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

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

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

288

Часть III. Объектно ориентированные сокеты

www.books-shop.com

тировать наследование, полиморфизм, интерфейсы классов и т.д. Это заставило многих изменить существующие подходы к тестированию.

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

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

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

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

Тестирование по методу черного ящика позволяет оценить систему с точки зрения конечного пользователя. Это напоминает приемочные испытания, когда правильность системы проверяется на основании типичных сценариев ее исполь зования.

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

Понятие системной интеграции

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

Резюме: зыбучие пески ООП

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

Глава 14. Ограничения объектно ориентированного...

289

www.books-shop.com

www.books-shop.com

Соседние файлы в папке СПО
  • #
    11.04.201527.19 Mб69Cpp4Unix.pdf
  • #
    11.04.201516.44 Mб52IP Arhitektura, protokoly, realizatsiya (vklyuchaya IP versii s IP Security).djvu
  • #
  • #
    11.04.201510.72 Mб51Стивенс. UNIX. Разработка сетевых приложений.djvu