ук 03.001.02 2011
DESCRIPTION
TRANSCRIPT
![Page 1: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/1.jpg)
УК 03.001.01-2011 Учебный курс. Обучение. ООП.
![Page 2: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/2.jpg)
Базовые понятия
![Page 3: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/3.jpg)
Объектно-ориентированное программирование (ООП) – это методология программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых является экземпляром определенного класса, а классы образуют иерархию наследования.
(КН 02.002-1995, стр. 52)
• Основным элементом абстракции являются объекты
• Каждый объект является экземпляром определенного класса
• Классы образуют иерархию наследования
![Page 4: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/4.jpg)
Ключевые характеристики ООП
Абстракция выделяет существенные характеристики некоторого объекта, отличающие его от всех других видов объектов и, таким образом, четко определяет его концептуальные границы с точки зрения наблюдателя.
(КН 02.002-1995, стр. 55)
• Внешнее поведение
• Барьер абстракции
• Неоднозначность выделения абстракции
• Абстракция и объект реального мира – не одно и тоже (пример: вещественные числа и числа с плавающей точкой)
• Задача: является ли квадрат прямоугольником?
![Page 5: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/5.jpg)
Инкапсуляция – это процесс отделения друг от друга элементов объекта, определяющих его устройство и поведение; инкапсуляция служит для того, чтобы изолировать контрактные обязательства абстракции от их реализации.
(КН 02.002-1995, стр. 63)
• Сокрытие данных лишь частный случай инкапсуляции
• Поведение представляется только с помощью методов
• Задача о множествах объектов
![Page 6: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/6.jpg)
Модульность – это свойство системы, которая может была разложена на внутренне связные, но слабо связанные между собой модули.
(КН 02.002-1995, стр. 69)
• Что первично класс или модуль?
Иерархия – это упорядочивание абстракций, расположение их по уровням.
(КН 02.002-1995, стр. 71)
• “is a” (наследование)
• “part of” (агрегация, композиция)
![Page 7: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/7.jpg)
Принципы ООП
![Page 8: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/8.jpg)
![Page 9: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/9.jpg)
Открыто-замкнутый принцип
• Инкрементная разработка;
• Количество строк кода, которые пишет программист, в единицу времени ограничено;
• Если изменяется существующий код, то, скорее всего, прироста функционала не происходит;
• Повторное использование.
Программная сущность (класс, модуль, функция и т.д.) должна быть открыта для расширения, но закрыта для модификаций.
(СТ 02.003-1995, стр. 1)
![Page 10: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/10.jpg)
Наследование ООП позволяет задавать фиксированную абстракцию, но описывающую неограниченную группу возможных поведений.
Поведение – это то, как объект действует и реагирует; поведение выражается в терминах состояния объекта и передачи сообщений.
(КН 02.002-1995, стр. 96) Необходимо избегать конструкций, которые создают закрытое
множество поведений: • switch (ПР 02.001) • Цепочка if/else (ПР 02.002) • Информация о типе во время выполнения (ПР 02.003) • Перечислимые типы (ПР 02.004) • Дублирование кода (ПР 01.001) • Все поля должны быть private (ПР 02.005) • Избегать использование глобальных переменных (ПР 01.002)
![Page 11: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/11.jpg)
Пример 1: Геометрические фигуры
class Shape
{
private ShapeType itsType;
private void DrawSquare();
private void DrawCircle();
public static void DrawAllShapes(Shape[] list)
{
for(Shape s : list)
{
switch (s.itsType)
{
case square:
DrawSquare();
break;
case circle:
DrawCircle();
break;
}
}
}
}
![Page 12: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/12.jpg)
interface Shape
{
void Draw();
}
class ShapeUtils
{
public static void DrawAllShapes(Shape[] list)
{
for(Shape s: list)
{
s.Draw();
}
}
}
class Square implements Shape
{
public void Draw()
{
}
}
![Page 13: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/13.jpg)
Пример 2: Рубрикатор
switch (article.Rubric) { case Auto: case Realty: filterPanels.Add(ucSearchOptions); break; case Job: switch (article.TypeID) { case Resume: filterPanels.Add(ucSeniorityPanel); filterPanels.Add(ucPricePanel); filterPanels.Add(ucWorkSchedulePanel); break; case Vacancy: filterPanels.Add(ucSeniorityPanel); filterPanels.Add(ucPricePanel); filterPanels.Add(ucWorkSchedulePanel); break; case Education: filterPanels.Add(ucPricePanel); break; } break; }
![Page 14: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/14.jpg)
siteRubricHelper.SetFilterOptions(panel);
public interface IRubricHelper
{
void SetFilterOptions(FilterPanel panel);
}
public class DefaultRubricHelper implements IRubricHelper
{
private FilterOptions ucSearchOptions;
public void SetFilterOptions(FilterPanel panel)
{
panel.Add(ucSearchOptions); }
}
![Page 15: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/15.jpg)
Стратегическая замкнутость
• Замкнутость не может быть 100%
• Замкнутость должна быть стратегической
• Проектирование ради стратегической замкнутости
• Паттерны проектирования – типовые примеры, обеспечивающие определенные виды замкнутости
![Page 16: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/16.jpg)
Принцип подстановки Б. Лисков
Метод, получающий по ссылке объект, должен использовать этот объект без точного знания того, объектом какого класса в иерархии наследования он является.
(СТ 02.004-1995, стр. 2)
![Page 17: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/17.jpg)
Пример 3: RTTI
void Draw(Shape s)
{
if (s instanceof Point)
{
DrawPoint(s as Point);
}
else if (s instanceof Circle)
{
DrawCircle(s as Circle);
}
else if(s instanceof Square)
{
DrawSquare(s as Square);
}
}
![Page 18: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/18.jpg)
Пример 4: Rectangle и Square class Rectangle
{
private double height;
private double width;
public double getHeight() { return height; }
public void setHeight(int value) { height = value; }
public double getWidth() { return width; }
public void setWidth(int value) { width = value; }
}
….
void f(Rectangle r)
{
r.setHeight (5);
r.setWidth (4);
Debug.Assert(r.getHeight() * r.getWidth() == 20);
}
class Square extends Rectangle
{
public void setHeight(int value)
{
super.setHeight(value);
super.setWidth(value);
}
public void setWidth(int value)
{
super.setHeight(value);
super.setWidth(value);
}
}
![Page 19: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/19.jpg)
• Построенные абстракции нельзя проверить на корректность сами по себе. Такую проверку можно выполнить лишь в контексте клиентов, использующих данные абстракции.
• Заранее построить очень гибкую модель “про запас” нельзя!
• Лучше использовать прототипирование
Прототип – самый простой вариант чего-либо, но содержащий самый сложный компонент.
![Page 20: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/20.jpg)
Принцип обращения зависимостей
Программа Copy void Copy()
{
int ch;
while ((ch = Keyboard()) != EOF)
{
WritePrinter(c);
}
}
enum OutputDevice
{
printer,
disk
};
void Copy(OutputDevice dev)
{
int c;
while ((c = ReadKeyboard()) != EOF)
{
if (dev == printer)
WritePrinter(c);
else
WriteDisk(c);
}
}
![Page 21: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/21.jpg)
interface IReader
{
int Read();
}
interface IWriter
{
void Write(char) = 0;
}
…
void Copy(IReader r, IWriter w)
{
int c;
while((c=r.Read()) != EOF)
w.Write(c);
}
…
![Page 22: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/22.jpg)
Схема зависимостей
![Page 23: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/23.jpg)
• Высокоуровневые модули не должны зависеть от низкоуровневых модулей. И те, и те должны зависеть от абстракций.
• Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.
(СТ 02.005-1995, 6)
![Page 24: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/24.jpg)
СЛОИ
![Page 25: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/25.jpg)
Пример 5: Лампочка
class Lamp
{
public void TurnOn() {…}
public void TurnOff() {…}
}
class Button
{
private Lamp lamp;
public Button(Lamp lamp) {this.lamp = lamp;}
public void Detect()
{
if(GetPhisicalState())
{
lamp.TurnOn();
}
else
{
lamp.TurnOff();
}
}
}
![Page 26: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/26.jpg)
interface IButtonClient
{
void TurnOn();
void TurnOff();
}
class Button
{
private IButtonClient client;
public Button(IButtonClient client)
{
this.client = client;
}
public void Detect()
{
if (GetPhisicalState())
{
client.TurnOn();
}
else
{
client.TurnOff();
}
}
}
class Lamp
{
public void SwitchOn() {…}
public void SwitchOff() {…}
}
class LampAdapter implements IButtonClient
{
private Lamp lamp;
public LampAdapter(Lamp lamp)
{
this.lamp = lamp;
}
public void TurnOn()
{
lamp.SwitchOn();
}
public void TurnOff()
{
lamp.SwitchOff();
}
}
![Page 27: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/27.jpg)
• Сторонний код должен быть скрыт за обертками, реализующими собственные интерфейсы (ПР 04.001)
• Обертки можно строить к старому наследуемому коду
• Переписывание не всегда самый лучший путь
![Page 28: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/28.jpg)
Принцип соответствия интерфейсов
interface IButtonClient
{
void TurnOn();
void TurnOff();
}
Interface ITimerClient
{
void OnTimeout();
}
class Lamp implements IButtonCLient, ITimerClient
{
public void TurnOn() {…}
public void TurnOff() {…}
public void OnTimeout() {…}
}
class Button
{
private IButtonClient;
public Button(IButtonClient client) {…}
public void Detect() {…}
}
class Timer
{
private ITimerClient client;
public void Timeout()
{
…
client.OnTimeout();
…
}
}
![Page 29: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/29.jpg)
class EmergencyLamp extends Lamp
{
public override void OnTimeout()
{
// нельзя включать и отключать по таймеру,
// поэтому пустая реализация
}
}
class Lamp implements IButtonClient
{
…
}
class ButtonToTimerClientAdapter implements ITimerClient
{
// см. пример адаптера для IButtonClient
}
Interface IEmergencyClient
{
void OnAlert();
}
class ButtonToEmergencyClientAdapter implements IEmergencyClient
{
// см. пример адаптера для IButtonClient
}
![Page 30: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/30.jpg)
• ITimerClient, IEmergencyClient, IButtonCLient – это разные множества объектов, но которые частично пересекаются
• Жирные интерфейсы сигнализируют об ошибках в проектировании
• Жирных интерфейсов следует избегать (ПР 02.006) Исключение: применение паттерна Compositor
![Page 31: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/31.jpg)
Клиенты не должны зависеть от тех интерфейсов, которые они не используют
(СТ 02.006-1996, стр. 5)
![Page 32: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/32.jpg)
• Абстракции нельзя проверить сами по себе, вне контекста использования!!!
• Часто программисты делают предложения по функционалу, основываясь на текущих возможностях реализации
• Подход к программированию: программный код как результат решения конкретной задачи
• Подход к программированию: писать программный код как набор инструментов для решения задач
![Page 33: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/33.jpg)
DI контейнеры как расширяемые фабрики
package examples.di;
public interface Greeting
{
String greet();
}
package examples.di.impl;
import examples.di.Greeting;
public class GreetingImpl implements Greeting
{
public String greet()
{
return "Hello World!";
}
}
![Page 34: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/34.jpg)
package examples.di;
public interface GreetingClient
{
void execute();
}
package examples.di.impl;
import examples.di.Greeting;
import examples.di.GreetingClient;
public class GreetingClientImpl implements GreetingClient
{
private Greeting greeting;
public GreetingClientImpl(Greeting greeting) { this.greeting = greeting; }
public void execute() { System.out.println(greeting.greet()); }
}
![Page 35: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/35.jpg)
package examples.di.main;
import examples.di.Greeting;
import examples.di.impl.GreetingClientImpl;
import examples.di.impl.GreetingImpl;
public class GreetingMain
{
public static void main(String[] args)
{
Greeting greeting = new GreetingImpl();
GreetingClientImpl greetingClient = new GreetingClientImpl(greeting);
greetingClient.execute();
}
}
![Page 36: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/36.jpg)
package examples.di.main;
import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.S2ContainerFactory;
import examples.di.GreetingClient;
public class GreetingMain3
{
private static final String PATH = "examples/di/dicon/GreetingMain3.dicon";
public static void main(String[] args)
{
S2Container container = S2ContainerFactory.create(PATH);
GreetingClient greetingClient = new GreetingClientImpl( container.getComponent("greeting”)
);
greetingClient.execute();
}
}
![Page 37: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/37.jpg)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE components PUBLIC"-//SEASAR//DTD S2Container 2.3//EN" "http://www.seasar.org/dtd/components23.dtd"> <components> <include path="aop.dicon"/> <component name="greeting” class="examples.di.impl.GreetingImpl"> <aspect>aop.traceInterceptor</aspect> </component> </components>
![Page 38: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/38.jpg)
package examples.di.impl;
import examples.di.Greeting;
import examples.di.GreetingClient;
public class GreetingClientImpl implements GreetingClient
{
private Greeting greeting;
public GreetingClientImpl()
{
S2Container container = S2ContainerFactory.create(PATH);
this.greeting = container.getComponent("greeting”);
}
public void execute() { System.out.println(greeting.greet()); }
}
![Page 39: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/39.jpg)
Принцип единой ответственности
Должна быть ровно одна причина для изменения класса
• Классы должны быть компактными (ПР 02.007)
• Следует избегать глубоких иерархий классов (ПР 02.008)
![Page 40: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/40.jpg)
Компоновка программы
• Разделяй и властвуй
• Структурирование
• Разная структура для разных объемов
• План выполнения запросов
• Объявления
![Page 41: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/41.jpg)
Модули
Каков критерий разбиения программы на модули?
Взаимосвязи между модулями? Принцип организации взаимосвязей?
Что первично: классы или модули?
Каким программным конструкциям соответствуют модули?
Какие цели преследуют модули?
![Page 42: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/42.jpg)
Принципы сцепления модулей
Принцип эквивалентности единиц повторного использования и релиза
Единица повторного использования является единицей релиза. Только компоненты, которые реализуются через систему управления проектами, могут быть эффективно повторно использованы. Такой единицей является модуль.
(СТ 02.007-1996, стр. 4)
![Page 43: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/43.jpg)
Обобщенный принцип повторного использования
Классы, входящие в состав модуля повторно используются все вместе. Если Вы повторно используете один, то Вам доступны все остальные.
(СТ 02.007-1996, стр. 5)
Обобщенный принцип замкнутости
Классы, входящие в состав пакета, должны быть закрыты по отношению к одним и тем же изменениям. Изменение, влияющее на пакет, оказывает воздействие на все классы, входящие в этот пакет (на затрагивая другие пакеты)
(СТ 02.007-1996, стр. 6)
![Page 44: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/44.jpg)
• В .Net модулем является сборка
• Разнесение классов по модулям нетривиальная задача
• Методы разнесения классов по модулям носит динамический характер
• Сначала создаются классы, затем выделяются модули
• Движущая сила: смещения акцента от возможности разработки до возможности повторного использования
• Один класс в одном файле (ПР 05.001)
![Page 45: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/45.jpg)
Принципы связывания пакетов
Принцип ациклических зависимостей.
Граф зависимостей между модулями должен быть ациклическим
(СТ 02.007-1996, стр. 6)
![Page 46: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/46.jpg)
Пример 5: Ациклический граф
![Page 47: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/47.jpg)
Пример 6: Циклический граф
![Page 48: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/48.jpg)
![Page 49: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/49.jpg)
Интеграционная штурмовщина
• Еженедельный билд
• Не успеваем вовремя его собрать, протестировать
• Большие накладные расходы на сборку билда
• Увеличиваются сроки между билдами
• Модули можно разрабатывать независимо друг от друга
• Релиз системы состоит из набора модулей, каждый из которых имеет свою версию
• Product Manager
![Page 50: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/50.jpg)
Стабильность
• Какие цели преследуют модули?
• Пример: программа копирования
• “Хорошая” зависимость – это зависимость от чего-то, что не слишком часто меняется
• Как измерить насколько зависимость хорошая?
Стабильность – способность системы функционировать, не изменяя собственную структуру и находиться в равновесии в течение определенного промежутка времени.
(Wikipedia.org)
![Page 51: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/51.jpg)
Принцип стабильных зависимостей
Модули должны зависеть только от более стабильных модулей.
(СТ 02.008-1996, стр. 8)
• Дизайн системы не может быть полностью стабильным
• Принцип обобщенной замкнутости
• Принцип единственной ответственности
![Page 52: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/52.jpg)
Метрики стабильности
• Центростремительная связность (Ca) – количество классов за пределами модуля, которые зависят от классов внутри модуля
• Центробежная связность (Ce) – количество классов внутри модуля, которые зависят от классов за пределами модуля
• Коэффициент нестабильности (I): I = Ce/(Ce+Ca) – I = 0 – максимально стабильный пакет
– I = 1 – максимально нестабильный пакет
![Page 53: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/53.jpg)
Принцип стабильных абстракций
Модули, которые максимально стабильны должны быть максимально абстрактны. Нестабильные модули должны быть конкретны. Абстрактность модуля должна быть обратно пропорциональна нестабильности.
(СТ 02.008-1996, стр. 11)
Абстрактность модуля = Абстрактные классы и интерфейсы/Общее число классов и интерфейсов
![Page 54: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/54.jpg)
![Page 55: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/55.jpg)
Итоги
• Изменения через написание нового без переписывания старого
• Полностью от переписывания отказаться нельзя, поэтому важно проектировать систему
• Цель проектирования – управлять замкнутостью
• Проектирование предшествует программированию
• Сначала классы, а потом модули
• Нет интеграционной штурмовщине
• Важно правильно разбивать систему на модули
• Интерфейсы рулят
![Page 56: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/56.jpg)
• Проектирование – Design Patterns
– Прототипирование как средство уменьшения рисков
• Существующий код – Рефакторинг
– Фасады
– Автоматическое тестирование
![Page 57: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/57.jpg)
Что дальше
• Контрактная модель программирования
• Design Patterns
• Рефакторинг
• Автоматическое тестирование
![Page 58: ук 03.001.02 2011](https://reader033.vdocuments.site/reader033/viewer/2022051412/549e72f3b4795992208b4780/html5/thumbnails/58.jpg)
Вопросы?