Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
GOS.pdf
Скачиваний:
172
Добавлен:
11.03.2015
Размер:
6.59 Mб
Скачать

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

Исходный код как главный проектный документ.

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

5 Рефакторинг. Цели, описание, примеры.

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

Цель рефакторинга — сделать код программы легче для понимания; без этого рефакторинг нельзя считать успешным.

Рефакторинг следует отличать от оптимизации производительности. Как и рефакторинг, оптимизация обычно не изменяет поведение программы, а только ускоряет еѐ работу. Но оптимизация часто затрудняет понимание кода, что противоположно рефакторингу.

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

Рефакторинг нужно применять постоянно при разработке кода. Основными стимулами его проведения являются следующие задачи:

1)необходимо добавить новую функцию, которая недостаточно укладывается в принятое архитектурное решение;

2)необходимо исправить ошибку, причины возникновения которой сразу не ясны;

3)преодоление трудностей в командной разработке, которые обусловлены сложной логикой программы.

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

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

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

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

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

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

Наиболее употребимые методы рефакторинга:

Изменение сигнатуры метода (Change Method Signature)

Инкапсуляция поля (Encapsulate Field)

Выделение класса (Extract Class)

Выделение интерфейса (Extract Interface)

Выделение локальной переменной (Extract Local Variable)

Выделение метода (Extract Method)

Генерализация типа (Generalize Type)

Встраивание (Inline)

Введение фабрики (Introduce Factory)

Введение параметра (Introduce Parameter)

Подъѐм поля/метода (Pull Up)

Спуск поля/метода (Push Down)

Замена условного оператора полиморфизмом (Replace Conditional with Polymorphism)

6 Системы управления версиями. Использование в проектах.

Система управления версиями (от англ. Version Control System, VCS или Revision

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

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

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

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

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

Многие системы управления версиями предоставляют ряд других возможностей:

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

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

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

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

Также известны распределенные системы контроля версий (англ. Distributed Version Control System, DVCS). Такие системы используют распределѐнную модель вместо традиционной клиент-серверной. Они, в общем случае, не нуждаются в централизованном хранилище: вся история изменения документов хранится на каждом компьютере, в локальном хранилище, и при необходимости отдельные фрагменты истории локального хранилища синхронизируются с аналогичным хранилищем на другом компьютере. В некоторых таких системах локальное хранилище располагается непосредственно в каталогах рабочей копии.

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

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

7 Тестирование. Виды тестирования. Разработка через тестирование.

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

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

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

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

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

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

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

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

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

Классификация методов тестирования.

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

Все существующие методы тестирования можно разделить на два основных класса - статическое и динамическое тестирование.

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

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

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

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

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

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

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

Уровни тестирования

Модульное тестирование (юнит-тестирование) — тестируется минимально возможный для тестирования компонент, например, отдельный класс или функция. Часто модульное тестирование осуществляется разработчиками ПО.

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

Системное тестирование — тестируется интегрированная система на еѐ соответствие требованиям.

Разработка через тестирование (test-driven development, TDD) — техника разработки программного обеспечения, которая основывается на повторении очень коротких циклов разработки: сначала пишется тест, покрывающий желаемое изменение, затем пишется код, который позволит пройти тест, и под конец проводится рефакторинг нового кода к

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

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]