разработка серверов и серверных приложений лекция №3

53
Глава 3. Модель акторов. 3 0

description

В третьей главе рассматриваются базовые свойства акторов, описанные в PhD диссертации Gul Agha: каждый актор имеет адрес, большой почтовый ящик, куда доставляются сообщения, адресованные актору и поведение. В ответ на входящее сообщение актор может отправить конечный набор сообщений другим акторам и/или создать конечное число новых акторов и/или поменять свое поведение для обработки следующего сообщения. В рамках данного курса будет разработана библиотека для разработки параллельных приложений на платформе .NET, построенная по модели акторов. Исходные коды библиотеки будут выкладываться на GitHub: https://github.com/hwdtech/HWdTech.DS Код библиотеки будет разработан с использованием следующих принципов, приемов и методик: S.O.L.I.D. - принципы Unit-tests Mock IoC контейнеры Для удобства слушателей курса краткий обзор данных практик приведен в Главе 4.

Transcript of разработка серверов и серверных приложений лекция №3

Page 1: разработка серверов и серверных приложений лекция №3

Глава 3. Модель акторов. 30

Page 2: разработка серверов и серверных приложений лекция №3

Actors: A Model of Concurrent Computations in Distributed Systems

PhD thesis, 1985

Литература 65

Gul A. Agha

Page 3: разработка серверов и серверных приложений лекция №3

1. Tag (уникальный идентификатор)2. Target (mail address)3. Communication (данные)

Task 66

Page 4: разработка серверов и серверных приложений лекция №3

Абстракция актора 67

1.Mail address2.Large mail queue3.Behavior

Page 5: разработка серверов и серверных приложений лекция №3

Шаг вычислений 68

1.Отправить сообщения2.Создать новые акторы3.Изменить свое

поведение для приема следующего сообщения (become method)

Page 6: разработка серверов и серверных приложений лекция №3

Литература 69

Page 7: разработка серверов и серверных приложений лекция №3

1. Каналы2. Сообщения3. Фильтры4. Маршрутизация5. Преобразование6. Конечные точки

Обмен сообщениями 70

Page 8: разработка серверов и серверных приложений лекция №3

Каналы 71

http://www.eaipatterns.com/MessageChannel.html

Page 9: разработка серверов и серверных приложений лекция №3

Сообщения 72

http://www.eaipatterns.com/Message.html

Page 10: разработка серверов и серверных приложений лекция №3

Маршрутизация 73

http://www.eaipatterns.com/MessageRouter.html

Page 11: разработка серверов и серверных приложений лекция №3

Конечные точки 74

http://www.eaipatterns.com/MessageEndpoint.html

Page 12: разработка серверов и серверных приложений лекция №3

Глава 4. Важно знать. 75

Page 13: разработка серверов и серверных приложений лекция №3

Библиотека акторов, котрая будет написана в рамках спецкурса выложена по адресу

https://github.com/hwdtech/HWdTech.DS

Репозиторий GitHub 76

Page 14: разработка серверов и серверных приложений лекция №3

• The Open-Closed Principle• The Liskov Substitution Principle• The Interface Segregation

Principle• The Dependency Inversion

Principle• The Single Responsibility

Principle

objectmentor.com

S.O.L.I.D 77

Rob Martin (Uncle Bob)

Page 15: разработка серверов и серверных приложений лекция №3

The Open-Closed Principle 78

Программные объекты должны быть открыты для расширения, но в тоже время закрыты для модификации

Page 16: разработка серверов и серверных приложений лекция №3

Открытые vs закрытые 79

• Полиморфная операция

• Паттерны• DI контейнеры• Код, ген. по

метаописанию

• switch• If /else – if/else• Неполиморфная

операция• операторы

приведения типа• enum

Page 17: разработка серверов и серверных приложений лекция №3

Открытые vs закрытые 80

• Полиморфная операция

• Паттерны• DI контейнеры• Код, ген. по

метаописанию

• …• Магические

константы• Copy-paste• Public поля• Глобальные

переменные

Page 18: разработка серверов и серверных приложений лекция №3

Открытые vs закрытые 81

• Полиморфная операция

• Паттерны• DI контейнеры• Код, ген. по

метаописанию

• …• Магические

константы• Copy-paste• Public поля• Глобальные

переменные

Page 19: разработка серверов и серверных приложений лекция №3

Программа Copy вер. 1 82

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 20: разработка серверов и серверных приложений лекция №3

Программа Copy вер. 2 83

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 21: разработка серверов и серверных приложений лекция №3

Все дело в зависимостях 84

Page 22: разработка серверов и серверных приложений лекция №3

The Dependency Inversion Principle85

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

Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.

Page 23: разработка серверов и серверных приложений лекция №3

Слои 86

Page 24: разработка серверов и серверных приложений лекция №3

Литература 87

Page 25: разработка серверов и серверных приложений лекция №3

Фасад 88

Page 26: разработка серверов и серверных приложений лекция №3

Абстрактная фабрика 89

void Copy( IReader r, IWriter w) { int c; while((c=r.Read()) != EOF) w.Write(c); }

Page 27: разработка серверов и серверных приложений лекция №3

DI Container Autofac 90

var builder = new ContainerBuilder();builder.RegisterType<LibraryBook>().As<IBook>();builder.RegisterType<MainViewModel>().AsSelf();var container = builder.Build();

var model = container.Resolve<MainViewModel>();var view = new MainWindow (DataContext = model);

view.Show();

Page 28: разработка серверов и серверных приложений лекция №3

Логика Хоара 91

Тройка Хоара {pred} statement {post}

Пример: Чарльз Хоар{x+1 == 43} y=x+1; {y == 43 ^ x == 42}

Page 29: разработка серверов и серверных приложений лекция №3

Аксиомы и правила логики Хоара 92

Аксиома пустого оператора {P} skip {P} Аксиома присваивания {P[E/x]} x := E {P} Правило композиции {P} S {Q}, {Q} T {R} {P} S;T {R} ╞Правило условного оператора {B ^ P} S {Q}, {B’ ^P} T {Q} {P} ╞ if B then S else T endif {Q} Правило вывода P1 → P, {P} S {Q}, Q → Q1 {P1} S {Q1} ╞Правило оператора цикла {P ^ B} S {P} {P} ╞ while B do S done {B’ ^ P}

Page 30: разработка серверов и серверных приложений лекция №3

Аксиомы и правила логики Хоара 93

Аксиома пустого оператора {P} skip {P} Аксиома присваивания {P[E/x]} x := E {P} Правило композиции {P} S {Q}, {Q} T {R} {P} S;T {R} ╞Правило условного оператора {B ^ P} S {Q}, {B’ ^P} T {Q} {P} ╞ if B then S else T endif {Q} Правило вывода P1 → P, {P} S {Q}, Q → Q1 {P1} S {Q1} ╞Правило оператора цикла {P ^ B} S {P} {P} ╞ while B do S done {B’ ^ P}

Page 31: разработка серверов и серверных приложений лекция №3

Пример: pow(x,y) 94

int power(int a, int n) {

assert(n > 0 || (a != 0 || n != 0));

if (n == 0) return 1;

else {

int a2 = power(a, n/2);

if (n & 1) return a*a2*a2;

else return a2*a2;

}

}

http://freehabr.ru/blog/programming/1933.html

Page 32: разработка серверов и серверных приложений лекция №3

Пример: pow(x,y) 95

int power(int a, int n) {

assert(n > 0 || (a != 0 || n != 0));

if (n == 0) return 1;

else {

int a2 = power(a, n/2);

if (n & 1) return a*a2*a2;

else return a2*a2;

}

}

http://freehabr.ru/blog/programming/1933.html

Page 33: разработка серверов и серверных приложений лекция №3

pow(x,y) - итерация 96

int power(int a, int n) {

assert(n > 0 || (a != 0 || n != 0));

int r = 1, a0 = a, n0 = n;

/* r == 1 and a0 == a and n0 == n and n >= 0 инвариант_цикла: a0**n0 == r*a**n ограничивающая_функция(n): n */

Page 34: разработка серверов и серверных приложений лекция №3

pow(x,y) - итерация 97

while(n > 0) {

/* n > 0 and ограничивающая_функция(n) > 0 and инвариант_цикла */ if (n & 1) r *= a;

/* (n - нечетно and a0**n0*a == r*a**n) or инвариант_цикла */ n >>= 1;

Page 35: разработка серверов и серверных приложений лекция №3

pow(x,y) - итерация 98

/* n == 0 and инвариант_цикла and ограничивающая_функция(n) == 0 */

// a0**n0 == r return r;

}

Page 36: разработка серверов и серверных приложений лекция №3

Правило композиции{P} S {Q}, {Q} T {R} {P} S;T {R}╞Проверку каждого оператора заменить на проверку группы операторов

Очень трудно! 99

Page 37: разработка серверов и серверных приложений лекция №3

Инвариант Предусловие Постусловие

Контрактное программирование 100

Page 38: разработка серверов и серверных приложений лекция №3

Следствия 101

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

Page 39: разработка серверов и серверных приложений лекция №3

Следствия 102

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

При нарушении условия выбрасывается исключение

Page 40: разработка серверов и серверных приложений лекция №3

Следствия 103

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

При нарушении условия выбрасывается исключение

Техника RAII

Page 41: разработка серверов и серверных приложений лекция №3

Следствия 104

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

При нарушении условия выбрасывается исключение

Техника RAIIМодульное тестирование

Page 42: разработка серверов и серверных приложений лекция №3

Модульное тестирование 105

Это всего лишь автоматизацияпроверки контракта

Page 43: разработка серверов и серверных приложений лекция №3

Модульное тестирование 106

1. Arrange2. Act3. Assert

Page 44: разработка серверов и серверных приложений лекция №3

Пример теста 107

Библиотека Nunit

using NUnit.Framework;[TestFixture]public class Tests { [Test] public void testStringReverse() { String input = "abc"; String result = Util.reverse(input); Assert.AreEquals("cba", result); }

Page 45: разработка серверов и серверных приложений лекция №3

Схема теста состояния 108

Page 46: разработка серверов и серверных приложений лекция №3

Недостатки 109

Тестирование основанное на состояниях: • Требует знания о внутреннем состоянии

объекта –возможно нарушение инкапсуляции

• Нарушает принципы ООП • Некоторые вещи трудно тестировать:

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

Page 47: разработка серверов и серверных приложений лекция №3

Но! А как же инкапсуляция? 110

Надо тестировать не состояние, а поведение!

Page 48: разработка серверов и серверных приложений лекция №3

Как тестировать поведение? 111

Полиморфизм: подменяя поведение серверного кода тестируем поведение клиентского

Page 49: разработка серверов и серверных приложений лекция №3

Что тестировать? 112

Был ли вызван метод?Сколько раз был вызван?Порядок вызова методовС какими параметрами?Что вернул на выходе?Выбросил ли исключение?

Page 50: разработка серверов и серверных приложений лекция №3

Пример Mock-теста 113

Библиотеки NUnit, Moq

[TestFixture] public class ActorTests { MockRepository repository = new MockRepository(MockBehavior.Strict); IMessage message;

[Test] public void AnActorShouldHandleAMessage() { Mock<Actor> actor = repository.Create<Actor>(); actor.Setup(a => a.Handle(message)).Verifiable();

actor.Object.Receive(message);

actor.VerifyAll(); }}

Page 51: разработка серверов и серверных приложений лекция №3

Mock-тесты схема 114

Page 52: разработка серверов и серверных приложений лекция №3

Принцип подстановки ЛисковФункции, которые используют ссылки на базовые классы, должны иметь возможность использовать объекты производных классов, не зная об этом.

Необходимое условие 1 115

Page 53: разработка серверов и серверных приложений лекция №3

Необходимое условие 2 116

Принцип обращения зависимостей

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

Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.