разработка серверов и серверных приложений лекция №3
DESCRIPTION
В третьей главе рассматриваются базовые свойства акторов, описанные в PhD диссертации Gul Agha: каждый актор имеет адрес, большой почтовый ящик, куда доставляются сообщения, адресованные актору и поведение. В ответ на входящее сообщение актор может отправить конечный набор сообщений другим акторам и/или создать конечное число новых акторов и/или поменять свое поведение для обработки следующего сообщения. В рамках данного курса будет разработана библиотека для разработки параллельных приложений на платформе .NET, построенная по модели акторов. Исходные коды библиотеки будут выкладываться на GitHub: https://github.com/hwdtech/HWdTech.DS Код библиотеки будет разработан с использованием следующих принципов, приемов и методик: S.O.L.I.D. - принципы Unit-tests Mock IoC контейнеры Для удобства слушателей курса краткий обзор данных практик приведен в Главе 4.TRANSCRIPT
![Page 1: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/1.jpg)
Глава 3. Модель акторов. 30
![Page 2: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/2.jpg)
Actors: A Model of Concurrent Computations in Distributed Systems
PhD thesis, 1985
Литература 65
Gul A. Agha
![Page 3: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/3.jpg)
1. Tag (уникальный идентификатор)2. Target (mail address)3. Communication (данные)
Task 66
![Page 4: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/4.jpg)
Абстракция актора 67
1.Mail address2.Large mail queue3.Behavior
![Page 5: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/5.jpg)
Шаг вычислений 68
1.Отправить сообщения2.Создать новые акторы3.Изменить свое
поведение для приема следующего сообщения (become method)
![Page 6: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/6.jpg)
Литература 69
![Page 7: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/7.jpg)
1. Каналы2. Сообщения3. Фильтры4. Маршрутизация5. Преобразование6. Конечные точки
Обмен сообщениями 70
![Page 8: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/8.jpg)
Каналы 71
http://www.eaipatterns.com/MessageChannel.html
![Page 9: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/9.jpg)
Сообщения 72
http://www.eaipatterns.com/Message.html
![Page 10: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/10.jpg)
Маршрутизация 73
http://www.eaipatterns.com/MessageRouter.html
![Page 11: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/11.jpg)
Конечные точки 74
http://www.eaipatterns.com/MessageEndpoint.html
![Page 12: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/12.jpg)
Глава 4. Важно знать. 75
![Page 13: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/13.jpg)
Библиотека акторов, котрая будет написана в рамках спецкурса выложена по адресу
https://github.com/hwdtech/HWdTech.DS
Репозиторий GitHub 76
![Page 14: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/14.jpg)
• 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](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/15.jpg)
The Open-Closed Principle 78
Программные объекты должны быть открыты для расширения, но в тоже время закрыты для модификации
![Page 16: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/16.jpg)
Открытые vs закрытые 79
• Полиморфная операция
• Паттерны• DI контейнеры• Код, ген. по
метаописанию
• switch• If /else – if/else• Неполиморфная
операция• операторы
приведения типа• enum
![Page 17: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/17.jpg)
Открытые vs закрытые 80
• Полиморфная операция
• Паттерны• DI контейнеры• Код, ген. по
метаописанию
• …• Магические
константы• Copy-paste• Public поля• Глобальные
переменные
![Page 18: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/18.jpg)
Открытые vs закрытые 81
• Полиморфная операция
• Паттерны• DI контейнеры• Код, ген. по
метаописанию
• …• Магические
константы• Copy-paste• Public поля• Глобальные
переменные
![Page 19: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/19.jpg)
Программа 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](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/20.jpg)
Программа 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](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/21.jpg)
Все дело в зависимостях 84
![Page 22: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/22.jpg)
The Dependency Inversion Principle85
Высокоуровневые компоненты не должны зависеть от низкоуровневых компонент. И те, и те должны зависеть от абстракций.
Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.
![Page 23: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/23.jpg)
Слои 86
![Page 24: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/24.jpg)
Литература 87
![Page 25: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/25.jpg)
Фасад 88
![Page 26: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/26.jpg)
Абстрактная фабрика 89
void Copy( IReader r, IWriter w) { int c; while((c=r.Read()) != EOF) w.Write(c); }
![Page 27: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/27.jpg)
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](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/28.jpg)
Логика Хоара 91
Тройка Хоара {pred} statement {post}
Пример: Чарльз Хоар{x+1 == 43} y=x+1; {y == 43 ^ x == 42}
![Page 29: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/29.jpg)
Аксиомы и правила логики Хоара 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](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/30.jpg)
Аксиомы и правила логики Хоара 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](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/31.jpg)
Пример: 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](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/32.jpg)
Пример: 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](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/33.jpg)
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](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/34.jpg)
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](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/35.jpg)
pow(x,y) - итерация 98
/* n == 0 and инвариант_цикла and ограничивающая_функция(n) == 0 */
// a0**n0 == r return r;
}
![Page 36: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/36.jpg)
Правило композиции{P} S {Q}, {Q} T {R} {P} S;T {R}╞Проверку каждого оператора заменить на проверку группы операторов
Очень трудно! 99
![Page 37: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/37.jpg)
Инвариант Предусловие Постусловие
Контрактное программирование 100
![Page 38: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/38.jpg)
Следствия 101
Конструктор используется для инвариантов класса
![Page 39: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/39.jpg)
Следствия 102
Конструктор используется для инвариантов класса
При нарушении условия выбрасывается исключение
![Page 40: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/40.jpg)
Следствия 103
Конструктор используется для инвариантов класса
При нарушении условия выбрасывается исключение
Техника RAII
![Page 41: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/41.jpg)
Следствия 104
Конструктор используется для инвариантов класса
При нарушении условия выбрасывается исключение
Техника RAIIМодульное тестирование
![Page 42: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/42.jpg)
Модульное тестирование 105
Это всего лишь автоматизацияпроверки контракта
![Page 43: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/43.jpg)
Модульное тестирование 106
1. Arrange2. Act3. Assert
![Page 44: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/44.jpg)
Пример теста 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](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/45.jpg)
Схема теста состояния 108
![Page 46: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/46.jpg)
Недостатки 109
Тестирование основанное на состояниях: • Требует знания о внутреннем состоянии
объекта –возможно нарушение инкапсуляции
• Нарушает принципы ООП • Некоторые вещи трудно тестировать:
закрытые свойства и методы, алгоритмическую сложность
![Page 47: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/47.jpg)
Но! А как же инкапсуляция? 110
Надо тестировать не состояние, а поведение!
![Page 48: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/48.jpg)
Как тестировать поведение? 111
Полиморфизм: подменяя поведение серверного кода тестируем поведение клиентского
![Page 49: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/49.jpg)
Что тестировать? 112
Был ли вызван метод?Сколько раз был вызван?Порядок вызова методовС какими параметрами?Что вернул на выходе?Выбросил ли исключение?
![Page 50: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/50.jpg)
Пример 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](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/51.jpg)
Mock-тесты схема 114
![Page 52: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/52.jpg)
Принцип подстановки ЛисковФункции, которые используют ссылки на базовые классы, должны иметь возможность использовать объекты производных классов, не зная об этом.
Необходимое условие 1 115
![Page 53: разработка серверов и серверных приложений лекция №3](https://reader034.vdocuments.us/reader034/viewer/2022052507/557ed25cd8b42a706f8b5059/html5/thumbnails/53.jpg)
Необходимое условие 2 116
Принцип обращения зависимостей
Высокоуровневые компоненты не должны зависеть от низкоуровневых компонент. И те, и те должны зависеть от абстракций.
Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.