dfe2e2bbea45aad0bbf2cb30b9b1df29.ppt
- Количество слайдов: 55
Программная инженерия
Программа курса • Программное обеспечение: природа и качество. Классификация ПО. Требования и показательные качества ПО. Виды систем. Принципы инженерии ПО. • Основные понятия объектноориентированного программирования. Объекты, сообщения, интерфейсы, классы, полиморфизм.
• Обзор языков, платформ, технологий и средств разработки. . NET Framework и J 2 EE – сравнительный анализ. Основы CORBA, DCOM, EJB, . NET Remoting. Реляционные и объектно-ориентированные базы данных. Интернет приложения, веб сервисы. Средства управления исходным кодом (CVS, Subversion, Source. Safe) • Стратегии распределенных вычислений. Связи. Процессы. Синхронизация. Репликация. Отказоустойчивость. Распределенные системы объектов, файлов, документов. Распределенные системы согласования.
• Проектирование, спецификация. Составление технических заданий. Методы сбора информации. UML. Use case диаграммы. Диаграммы классов, объектов, компонентов, состояний, последовательностей, действий. ORM. CASE инструменты. Спецификации асинхронных систем. Логические, алгебраические спецификации. Концептуальный, логический и физический дизайн. Прототипирование. Паттерны проектирования. • Процесс разработки программного обеспечения. Структура проектной группы. Стадии проекта. Нотации оформления кода. cамодокументированность кода. Рефакторинг. Экстремальное программирование. Безопасность кода. Принципы построения GUI. Ведение параллельных версий. Компиляция и отладка ПО. Оптимизация.
• Тестирование. Верификация. Методы тестирования (методы “черного и белого ящика”) Планы тестирования проекта, компонентов. Модели анализа. Автоматизированные регрессивные тесты. Тестирование классов и иерархий классов. Тестирование распределенных объектов. Тестирование интернет приложений. • Внедрение продукта. Разработка пользовательской документации. Создание программы установки. Обучение пользователей, поддержка ПО. Повторное использование и переносимость ПО, реинженерия.
Управление. • Планирование проекта. Анализ рисков. Оценка затрат. Внутренняя проектная документация. Командная работа, распределение ролей и ответственности (централизованный, децентрализованный и смешанный тип управления). Диаграммы Ганта. Графики PERT. Контроль качества. Анализ текущего состояния проекта. Стабильность/нестабильность проекта, построение графиков интенсивности возникновения и устранения ошибок. Средства поддержки управления проектом. Модель развития функциональных возможностей CMM.
Литература • • Мартин Фаулер Архитектура корпоративных программых приложений. Москва. Изд. Вильямс 2004. Карло Гецци, Мехди Джазайери, Дино Мандриоли. Основы инженерии программного обеспечения. Санкт-Петербург БХВ 2005. Э. Таненбаум, М. ван Стеен. Распределенные системы. Принципы и парадигмы. Изд. Питер 2004. Джон Макгрегор, Девид Сайкс Тестирование объектноориентированного программного обеспечения. 2002 Beck. Test-Driven Development: By Example. Addison-Wisley, 2003. Эд Салливан. Время-деньги. Microsoft Press, Русская редакция. Москва 2002. Бек, К. Экстремальное программирование. Библиотека программиста. СПб. : Питер, 2002.
Жизненный цикл программного обеспечения. • Envisioning. Анализ и спецификация требований. • Planning. Проектирование. • Developing. Кодирование. • Stabilizing. Тестирование. • Deploying. Сборка. Поставка и эксплуатация.
Качества программного обеспечения • Внутренние и внешние качества, связь между ними. • Оценка продукта. • Оценка процесса создания ПО.
• Корректность (correctness) – соответствие требованиям функциональной спецификации • Надежность (reliability) – вероятность того, что программное обеспечение будет работать как ожидалось в течении определенного интервала времени. Надежность Корректность • Устойчивость(stability) – правильное поведение программы даже в обстоятельствах не предусмотренных в спецификации
• Производительность (productivity). • Эффективность (performance). Подходы к расчету производительности системы: 1. 2. 3. Измерение Анализ Имитационное моделирование. • Удобство. Дружественный интерфейс. • Верифицируемость.
• Рассмотреть влияние пользовательского интерфейса (GUI) на надежность.
Сопровождаемость В среднем затраты на сопровождение превышают 60% от общей стоимости программного обеспечения. Категории сопровождения • Корректирующее – устранение ошибок. • Настраивающее – адаптация приложения к изменениям среды. • Усовершенствующее – изменение ПО с целью улучшения некоторых из его качеств. Проблема унаследованного ПО. Необходимость проведение обратного инжиниринга и реинженеринга.
• Ремонтопригодность (repairability) – возможность устранения дефектов приемлемыми усилиями. • Способность к эволюции. • Повторная применимость. • Переносимость (portability) – возможность работать в различных системах. • Понятность. • Интероперабельность (interoperability) – возможность ПО сотрудничать с другими системами. • Продуктивность.
• Как повторная применимость может влиять на надежность продуктов? • Как можно использовать наследование для увеличения повторной применимости? • Какова связь повторной применимости и переносимости? • Как можно применить переносимость для web страниц? • Что можно сказать о способности к эволюции открытых систем? • Можно ли использовать подсчет количества строк кода для измерения продуктивности?
Своевременность ПО Функциональность Требования пользователя Реальные возможности системы T 0 T 1 T 2 T 3 Наиболее часто встречающиеся проблемы в разработке ПО.
Классификация ПО. • Информационные системы. Хранение, поиск, извлечение данных. • Системы реального времени. Должны реагировать на событие в течении строго предопределенного периода времени. • Распределенные системы. Располагаются на нескольких независимых или частично независимых компьютерах. • Встроенные системы. ПО является одним из множества компонентов, часто не имеют GUI.
• Охарактеризуйте такие качества как тестируемость, целостность, легкость в использовании, изучаемость. Приведите примеры. • Оценить преимущества и недостатки повторной используемости методов в применении к программному процессу. • Какова роль протоколов TCP/IP в интероперабельности? • Можно ли оценивать процесс создания ПО с точки зрения интероперабельности?
Принципы создания ПО. Принципы Методы и приемы Методологии Инструментальные средства
• Строгость и формальность. • Разделение задач. Преимущества и недостатки (избыточность, взаимоблокировки). • Модульность. Проектирование снизу вверх и сверху вниз.
Преимущества модульности. • Разложимость – возможность разложить систему на простые части. • Компонуемость – возможность собрать систему из готовых модулей. • Возможность интерпретировать систему как состоящую из простых частей. • Возможность модифицировать систему путем модификации небольшого количества частей.
Внутримодульная и межмодульная связность. А Б
• Какие могут быть причины низкой внутримодульной связности? Как их устранить? • Какие могут быть причины высокой межмодульной связности? Как их устранить?
Абстракция Выделяем существенные аспекты явления и игнорируем его подробности. • Переменные в языках программирования можно рассматривать как абстракции адресов ячеек памяти. От каких подробностей абстрагируются переменные языков программирования? Каковы преимущества и недостатки использования такой абстракции? • Модель жизненного цикла ПО является абстракцией программного процесса. Почему? • Какие абстракции полезны конечному пользователю, проектировщику и специалисту по поддержке приложений?
• Предусмотрение изменений. Принцип позднего связывания. • Общность. Каждый раз, когда надо решить какую-либо проблему, постарайтесь сосредоточится на решении более общей проблемы, которая может быть скрыта за рассматриваемой задачей. • Инкрементность. Итерационный процесс разработки. Способ получения раннего отклика от клиента.
• Какое взаимоотношение между обобщением и предусмотрением изменений? • Какое взаимоотношение между общностью и абстракцией? • Какое взаимоотношение между формальностью и предусмотрением изменений?
Парадигмы программирования • Будем говорить, что язык поддерживает данный стиль программирования, если он предоставляет средства, которые делают использование стиля удобным (достаточно простым, надежным и эффективным) • Язык не поддерживает технику программирования, если для написания соответствующей программы требуются чрезмерные усилия или мастерство.
Процедурное программирование Реши, какие требуются процедуры; используй наилучшие доступные алгоритмы. Пример. double sqrt(double arg) { //text } void f() { double root 2 = sqrt(2); }
Модульное программирование Реши, какие требуются модули; разбей программу так, чтобы скрыть данные в модулях. Пример. Реализовать стек, удовлетворяющий следующим требованиям: 1. Предоставить пользовательский интерфейс для стека (например, функции push() и pop(), помещающий данные в стек и извлекающий их оттуда) 2. Гарантировать, что представление стека доступно только через этот пользовательский интерфейс. 3. Обеспечить инициализацию стека до первого использования.
namespace Stack { //интерфейс void push(char); char pop(); } void f() { Stack: : push(‘c’); if(Stack: : pop()!=‘c’) error (“Такое невозможно”); } namespace Stack{ //реализация const int max_size = 200; char v[max_size]; int top = 0; void push(char c){/*Поместить в стек. */} char pop() {/*Извлечь из стека. */} }
Раздельная компиляция stack. h Интерфейс стека user. cpp #include “stack. h” Использование стека stack. cpp #include “stack. h” Использование стека
Модули, определяющие типы namespace Stack { struct Rep; typedef Rep& stack; stack create(); void destroy(stack s); void push(stack s, char с); char pop(stack s); } void f() { Stack: : stack s 1 = Stack: : create(); //Создать новый стек Stack: : stack s 2 = Stack: : create(); //и еще один
Stack: : push(s 1, ’c’); Stack: : push(s 2, ’k’); If(Stack: : pop(s 1)!=‘c’) throw Bad. Pop(); If(Stack: : pop(s 2)!=‘k’) throw Bad. Pop(); Stack: : destroy(s 1); Stack: : destroy(s 2); } namespace Stack{ struct Rep{ char v[max_size]; int top; }; const int max = 16; Rep stacks[max]; … }
Объектно-ориентированное программирование Реши, какие требуются классы; обеспечь полный набор операций для каждого класса; явно вырази общность через наследование. • Инкапсуляция – объединение в единое целое данных и алгоритмов обработки этих данных. • Наследование – свойство объектов порождать своих потомков. • Полиморфизм – свойство родственных объектов (имеющих общего родителя) решать схожие по смыслу проблемы разными способами.
Классический пример для случая отображения различных фигур: А. Диаграмма классов. В. Объединение классов в единый пакет.
Определение наследников class Circle extends Shape {…} // java class Circle: Shape {…} // C# Пример создания общих методов для всех наследников: void rotate(Shape s, int angle) { s. rotate(angle); s. draw(); } Circle c = new Circle(); Polygon p = new Polygon(); rotate(c, 60); rotate(p, 40);
• Можно ли при создании класса Circle воспользоваться реализацией из класса Shape не применяя наследование? Если возможно, то как? • Всегда ли использование наследования несет только преимущества? • Приведите примеры возможного использования наследования.
Более сложный пример использования наследования.
Множественное наследование В отличии от C++ для Java и. NET множественное наследование от обычных классов не поддерживается. Оно заменяется на одиночное наследование от обычного класса и множественное от интерфейсов. Реализация серверного класса в NET Remoting.
Модификаторы доступа • Private – доступен только методам в определяющем типе и вложенных в него типах. • Protected – доступен только методам в этом типе или одном из производных типов. • Public – доступен всем методам. Нестандартные модификаторы доступа и атрибуты в разных языках: internal, friend, abstract, sealed, final, readonly Атрибут static (Shared) – означает, что поле частично определяет состояние типа, а не объекта.
Члены класса • Константа – идентификатор, определяющий некую постоянную величину. public const Int 32 Max. Entiries. In. List = 50; • Поле – неизменяемое или изменяемое значение, определяющее состояние типа или объекта (статическое или нестатическое) public static readonly Random = new Random(); static Int 32 number. Of. Writes = 0; public readonly String path. Name =“Untitled”; public File. Stream fs;
• Конструктор экземпляра – метод, используемый для установки в корректное начальное состояние экземпляров полей нового объекта. class Some. Type{ Int 32 x; String s; public Some. Type(){/* Общая часть */} public Some. Type(Int 32 x): this(){ this. x = x; } public Some. Type(String s): this(){ this. s = s; } }
• Конструктор типа (статический конструктор, конструктор класса, инициализатор типа) – метод, используемый для установки в корректное начальное состояние статических полей типа. class Some. Type { static Int 32 x = 5; static Some. Type() { x = 10; } } Чему будет равна переменная x после обращения к классу Some. Type?
• Метод – функция, выполняющая операции, которые изменяют или опрашивают состояние типа(статический метод) или объекта (экземплярный метод). public static Boolean Reference. Equals(Object, obj. AObject obj. B) static void Set. Val(out Int 32 v) {…} void Add. Val(ref Int 32 v) {…} static Int 32 Add(params Int 32[] values) {…} • Перегрузка оператора – метод, определяющий, что нужно проделать с объектом, применении к нему оператора. Class Complex { public static Complex operator+(Complex c 1, Complex c 2) {…} }
• Оператор преобразования – метод, определяющий как неявно/явно привести объект из одного типа в другой. Class Rational { public Rational(Int 32 numerator) {…} public Rational(Single value) {…} public Int 32 To. Int 32() {…} public Single To. Single() {…} //Неявно создает Rational из Int 32 и Single public static implicit operator Rational(Int 32 numerator) { return new Rational(numerator); } public static implicit operator Rational(Single value) { return new Rational(value); }
//Явно возвращает объект типа Int 32, полученный из Rational public static explicit operator Int 32(Rational r) { return r. To. Int 32(); } //Явно возвращает объект типа Single, полученный из Rational public static explicit operator Single(Rational r) { return r. To. Single(); } } Пример использования: Rational r 1 = 5; //Неявное приведение Int 32 к Rational r 2 = 1. 202 e 18; //Неявное приведение Single к Rational Int 32 x = (Int 32) r 1; //Явное приведение Rational к Int 32 Single s = (Single) r 2; //Явное приведение Rational к Single
• Свойство – метод, который позволяет применить простой синтаксис для установки или получения части логического состояния типа или объекта, не нарушая это состояние. public class Employee { private String _Name; private Int 32 _Age; //Ключевое слово value идентифицирует //новое значение public String Name { get { return _Name; } set { _Name = value; } }
public Int 32 Age { get { return _Age; } set { if (value < 0) throw new Out. Of. Rage. Exception(); _Age = value; } } }
• Событие (статическое, экземплярное) – механизм, который позволяет типу/объекту посылать уведомление слушающему типу/объекту. Объявление события в C# public delegate void Data. Changed. Delegate ( Event. Value. Changed val); public event Data. Changed. Delegate Data. Changed; if(Data. Changed !=null ) Data. Changed(null); //вызов ((IForm)_table. Form). Data. Changed += new Data. Changed. Delegate( Control. Constructor. List. Form_Data. Changed); Пример подписки на события компонентов Swing (java) JText. Field name = new JText. Field(25); Class Name. L implements Action. Listner {…} name. add. Action. Listner(new Name. L());
Исключения • Компактное размещение кода, выполняющего очистку, и его гарантированное исполнение. • Централизованное хранение кода, имеющего дело с исключительными ситуациями. • Облегчение поиска и исправления ошибок в коде. Следует отметить, что при разработке API Win 32 и COM Microsoft отказались от использования исключений для уведомления вызывающего кода о сбоях. Вопрос: Какая методика используется в API Win 32 и COM?
void Some. Method() { try { } catch (Invalid. Cast. Exception) { } catch (Null. Reference. Exception) { } catch (Exception e) { throw; } catch { throw; } finally { } }
Обобщенное программирование Реши, какие требуются алгоритмы; параметризируй их так, чтобы они могли работать со множеством подходящих типов и структур данных. Шаблоны в C++ template<class T> class Stack { T * v; int max_size; int top; public: Stack (int s); ~Stack(); void push(T); T pop (); }
Префикс template<class T> делает T параметром объявления, которому этот префикс предшествует. Функции-члены можно определить следующим образом: template<class T> void Stack<T>: : push(T c) { if (top == max_size) throw Overflow (); v[top] = c; top ++; } Использование стека: Stack<char> sc (200); Stack<complex> scplx(30); sc. push(‘c’); scplx. push (complex(1, 2));
Generic в C# 2. 0 List<int> items = new List<int> (); items. Add(1); items. Add(2); items[1]++; int I = items[1]; //Объявление class List<Item. Type> {…}
Generic в java sdk 1. 5 List<String> items = new Array. List<String> (); items. Add(“some text”); String str = items. get(0); //Объявление class Generic. List<E> {…}
dfe2e2bbea45aad0bbf2cb30b9b1df29.ppt