Повторное использование (Reusability)
Повторное использование - способность элементов ПО служить для построения многих различных приложений.
Необходимость и возможность повторного использования возникает из наблюдений сходства систем - системы ПО часто имеют похожую схему. Следует использовать это сходство. Понимание этой схемы даст возможность повторно применять созданный элемент ПО во многих других разработках.
Повторное использование влияет на все остальные аспекты качества ПО. Поскольку решение проблемы повторного использования, в сущности, означает, что нужно писать меньше программ, следовательно, можно прилагать больше усилий (при той же общей стоимости) к улучшению других факторов, таких как, например, корректность и устойчивость.
При создании индустрии ПО необходимость повторного использования становится насущной проблемой.
Совместимость (Compatibility)
Совместимость - это легкость сочетания одних элементов ПО с другими.
Совместимость важна, поскольку мы не разрабатываем элементы ПО в вакууме: им необходимо взаимодействовать друг с другом. Но при этом слишком часто возникают проблемы, поскольку суждения разных элементов об остальном мире противоречивы. Простейшим примером может служить широкое разнообразие несовместимых файловых форматов, из-за чего, например, одна программа не может непосредственно использовать результат работы другой программы.
Ключ к совместимости находится в однородности построения и в стандартных соглашениях на коммуникации между программами. Эти подходы включают:
· Стандартные форматы файлов, как в системе Unix, где каждый текстовый файл - это просто последовательность символов.
· Стандартные структуры данных, как в системе Lisp, где все данные, а также программы, представлены бинарными деревьями (называемыми списками).
· Стандартные пользовательские интерфейсы, как в различных версиях Windows, OS/2 и MacOS, где все инструменты опираются на единую парадигму для коммуникации с пользователем, основанную на стандартных компонентах, таких как окна, значки, меню и т. д.
Большая общность достигается при определении стандартных протоколов доступа ко всем важным элементам, управляемым программами.
Совместимость: метод обеспечивает общий стиль проектирования и стандартизацию интерфейсов модулей и систем, что помогает совместно работать разным системам
Расширяемость (Extendibility)
Расширяемость - это легкость адаптации ПО к изменениям спецификации.
Предполагается, что ПО должно быть гибким (soft), и в принципе, оно такое и есть; ничего нет проще, чем изменить программу, если у вас есть доступ к ее исходному коду.
Проблема расширяемости это проблема масштаба. Для маленьких программ изменение не является обычно большой проблемой, но по мере увеличения ПО адаптация становится все труднее. Большая программная система часто видится как огромный карточный дом, удаление одного элемента может привести к разрушению всего построения.
Традиционные подходы к построению ПО не уделяли должного внимания изменениям. Они скорее исходили из идеального взгляда на жизненный цикл ПО, где требования замораживаются после завершения первоначальной ступени анализа. Последующий процесс посвящался проектированию и построению решения при фиксированных требованиях. На том этапе развития дисциплины задача состояла в разработке надежных технических приемов для постановки и решения фиксированных проблем.
Сейчас стало возможным признать и рассмотреть центральный вопрос - что делать, если проблема изменяется в ходе ее решения. Изменения характерны для процесса разработки ПО: меняются требования, наше понимание требований, алгоритмы, представление данных, приемы реализации. Поддержка изменений является основной целью объектной технологии и постоянной темой нашей книги.
Для улучшения расширяемости важны два принципа:
· Простота построения: простая архитектура легче адаптируется к изменениям, чем сложная.
· Децентрализация: чем более автономны модули, тем выше вероятность того, что простое изменение затронет только один или небольшое количество модулей и не вызовет цепную реакцию изменений во всей системе.
Билет 12
Описание объекта. Использование объекта. Наследование. Полиморфизм.
Объект – структура данных, содержащая описание свойств внешнего объекта программирования. Метод – функция, работающая с объектом. Класс – описание структуры объекта и методов работы с ним. Объект – замкнутые, логически непротиворечивые, всегда корректные данные с четко определенным универсальным интерфейсом доступа к ним
Синтаксическое определение объекта и класса - структура со встроенными функциями. Структурированная переменная со встроенными в нее функциями идеально подходит под определение объекта.
Свойства объекта: закрытость, независимость, универсальность, целостность.
Класс – это описание объектов, объект – это отображение класса в памяти. «объект-метод» преобразуется в традиционную последовательность действий: «вызов функции – метода класса с фактическим параметром – указателем на текущий объект».
Наследование:ключевое свойство ООП, позволяя применять принцип расширяемости решая проблемы повторяемости и изменчивости. С++ не поддерживает множественное наследование. Поэтому класс может наследовать только один непосредственный базовый класс. Применимо только к классам. Позволяет избежать дублирование лишнего кода при написании программы.
Полиморфизм: способность объекта вести себя по-разному в зависимости от того, как он используется.
Полиморфизм - это свойство, которое позволяет одно и то же имя использовать для решения двух или более схожих, но технически разных задач. Целью полиморфизма, применительно к объектно-ориентированному программированию, является использование одного имени для задания общих для класса действий.
В более общем смысле, концепцией полиморфизма является идея "один интерфейс, множество методов". Это означает, что можно создать общий интерфейс для группы близких по смыслу действий. Преимуществом полиморфизма является то, что он помогает снижать сложность программ, разрешая использование того же интерфейса для задания единого класса действий.
Выбор же конкретного действия, в зависимости от ситуации, возлагается на компилятор. Вам, как программисту, не нужно делать этот выбор самому. Нужно только помнить и использовать общий интерфейс.
Фактически во всех языках программирования ограниченно применяется полиморфизм, например, в арифметических операторах.
Ключевым в понимании полиморфизма является то, что он позволяет вам манипулировать объектами различной степени сложности путём создания общего для них стандартного интерфейса для реализации похожих действий.
Билет 13
Поддержка ОО-разработки в С++
Объектно-ориентированная разработка программ помогает справиться с такими сложными проблемами, как:
1) уменьшение сложности программного обеспечения;
2) повышение надежности программного обеспечения;
3) обеспечение возможности модификации отдельных компонентов программного обеспечения без изменения остальных его компонентов;
4) обеспечение возможности повторного использования отдельных компонентов программного обеспечения.
Систематическое применение объектно-ориентированного подхода к разработке программ позволяет разрабатывать хорошо структурированные, надежные в эксплуатации, достаточно просто модифицируемые программные системы. В настоящее время объектно-ориентированная разработка программ является одним из наиболее интенсивно развивающихся направлений в теоретическом и прикладном программировании.
Объектно-ориентированная разработка программного обеспечения использует инструментальные средства, поддерживающие объектно-ориентированные методологии (технологии) и связана с применением объектно-ориентированных моделей при разработке программных систем и их компонентов.
Можно назвать разные объектно-ориентированные методологии, например, SA/SD (Structured Analysis/Structured Design), JSD (Jackson Structured Development), OSA (Object-Oriented System Analysis).
Одной из наиболее продвинутых и популярных объектно-ориенти-рованных методологий является ОМТ (Object Modeling Technique). Ее графический язык (система обозначений для диаграмм) получил достаточно широкое распространение и используется в некоторых других объектно-ориентированных методологиях, а также в большинстве публикаций по объектно-ориентированным методологиям. Методология ОМТ полностью поддерживается системойParadium+, одной из наиболее известных инструментальных систем объектно-ориентированной разработки.
Билет 14
Средства автоматизации разработки программ. Функциональные особенности CASE-систем.
CASE (англ. Computer-Aided Software Engineering) — набор инструментов и методов программной инженерии для проектирования программного обеспечения, который помогает обеспечить высокое качество программ, отсутствие ошибок и простоту в обслуживании программных продуктов
Средства автоматизации разработки программ (CASE-средства) — инструменты автоматизации процессов проектирования и разработки программного обеспечения для системного аналитика, разработчика ПО и программиста. Первоначально под CASE-средствами понимались только инструменты для упрощения наиболее трудоёмких процессов анализа и проектирования, но позже их стали определять как программные средства для поддержки процессов жизненного цикла ПО.
Основной целью CASE-технологии является разграничение процесса проектирования программных продуктов от процесса кодирования и последующих этапов разработки, максимально автоматизировать процесс разработки.
Для выполнения поставленной цели CASE-технологии используют два принципиально разных подхода к проектированию: структурный и объектно-ориентированный.
Структурный подход предполагает декомпозицию (разделение) поставленной задачи на функции, которые необходимо автоматизировать. В свою очередь, функции также разбиваются на подфункции, задачи, процедуры. В результате получается упорядоченная иерархия функций и передаваемой информацией между функциями.
Основным инструментом объектно-ориентированного подхода является язык UML — унифицированный язык моделирования, который предназначен для визуализации и документирования объектно-ориентированных систем с ориентацией их на разработку программного обеспечения. Данный язык включает в себя систему различных диаграмм, на основании которых может быть построено представление о проектируемой системе.
В функции CASE входят средства анализа, проектирования и программирования программных средств, проектирования интерфейсов, документирования и производства структурированного кода на каком-либо языке программирования.
CASE-инструменты классифицируются по типам и категориям.
Классификация по типам отражает функциональную ориентацию средств на те или иные процессы жизненного цикла разработки программного обеспечения, и, в основном, совпадают с компонентным составом крупных интегрированных CASE-систем, и включают следующие типы:
· средства анализа — предназначены для построения и анализа модели предметной области;
· средства проектирования баз данных;
· средства разработки приложений;
· средства планирования и управления проектом;
· средства тестирования;
· средства документирования.
Типичными CASE-инструментами являются:
· инструменты управления конфигурацией;
· инструменты моделирования данных;
· инструменты анализа и проектирования;
· инструменты преобразования моделей;
· инструменты редактирования программного кода;
· инструменты рефакторинга кода;
· генераторы кода;
· инструменты для построения UML-диаграмм.
Билет 15
Модульное и интеграционное тестирования
Модульное тестирование - это тестирование программы на уровне отдельно взятых модулей, функций или классов.
Традиционное определение модуля с точки зрения его тестирования: "модуль – это компонент минимального размера, который может быть независимо протестирован в ходе верификации программной системы"
Цель: выявление локализованных в модуле ошибок в реализации алгоритмов, а также в определении степени готовности системы к переходу на следующий уровень разработки и тестирования. Ошибки, связанные с некорректной реализацией интерфейсов, совместимостью, производительностью и т.п. обычно пропускаются на уровне модульного тестирования и выявляются на более поздних стадиях тестирования.
Модульное тестирование обычно подразумевает создание вокруг каждого модуля определенной среды, включающей заглушки для всех интерфейсов тестируемого модуля. Некоторые из них могут использоваться для подачи входных значений, другие для анализа результатов, присутствие третьих может быть продиктовано требованиями, накладываемыми компилятором и сборщиком.
Именно эффективность обнаружения тех или иных типов дефектов должна определять стратегию модульного тестирования, то есть расстановку акцентов при определении набора входных значений.
В силу того, что модули, подвергаемые тестированию, обычно невелики по размеру, модульное тестирование считается наиболее простым (хотя и достаточно трудоемким) этапом тестирования системы. Однако, несмотря на внешнюю простоту, с модульным тестированием связано две проблемы.
1. Не существует единых принципов определения того, что в точности является отдельным модулем.
модуль – это часть программного кода, выполняющая одну функцию с точки зрения функциональных требований;
модуль – это программный модуль, т.е. минимальный компилируемый элемент программной системы;
модуль – это задача в списке задач проекта (с точки зрения его менеджера);
модуль – это участок кода, который может уместиться на одном экране или одном листе бумаги;
модуль – это один класс или их множество с единым интерфейсом.
2. Различия в трактовке самого понятия модульного тестирования – понимается ли под ним обособленное тестирование модуля, работа которого поддерживается только тестовым окружением, или речь идет о проверке корректности работы модуля в составе уже разработанной системы. В последнее время термин "модульное тестирование" чаще используется во втором смысле, хотя в этом случае речь скорее идет об интеграционном тестировании.
Но всё же модульное тестирование имеет такие преимущества, как упрощение интеграции, поощрение изменений, документирование кода и отделение интерфейса от реализации.
Поощрение изменений
Модульное тестирование позже позволяет программистам проводить реорганизацию кода (процесс изменения внутренней структуры программы). Это поощряет программистов к изменениям кода, поскольку достаточно легко проверить, что код работает и после изменений.
Упрощение интеграции
Модульное тестирование помогает устранить сомнения по поводу отдельных модулей и может быть использовано для подхода к тестированию «снизу вверх»: сначала тестируя отдельные части программы, а затем программу в целом.
Документирование кода
Модульные тесты можно рассматривать как «живой документ» для тестируемого класса. Клиенты, которые не знают, как использовать данный класс, могут использовать юнит-тест в качестве примера.