Как приручить реактивное программирование
TRANSCRIPT
![Page 1: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/1.jpg)
Как приручить реактивное программирование
Денис ЦветцихIce Rock Dev
icerockdev.com
12-я конференция .NET разработчиков15 мая 2016dotnetconf.ru
![Page 2: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/2.jpg)
2
Кто я?• 7+ лет .NET• Разработка корпоративных
приложений• Люблю хипстерские библиотеки
![Page 3: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/3.jpg)
3
Почему я здесь?• 6 лет назад приручил Rx• 3 года назад приручил ReactiveUI• С тех пор активно использую в
XAML проектах
![Page 4: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/4.jpg)
4
Многие не используют• Не знают о Rx и ReactiveUI• Находятся под влиянием «мифов»
о реактивном программировании
![Page 5: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/5.jpg)
5
О чем мы поговорим?• Что такое реактивное
программирование?• Для каких задач его использовать?• Развеем мифы, которые мешают его
использовать
![Page 6: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/6.jpg)
6
Опрос• Кто не знает, что такое реактивное
программирование?• Кто знаком с Rx и ReactiveUI, но не
решился использовать в своих проектах?
• Кто использовал Rx или ReactiveUI на продакшене?
![Page 7: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/7.jpg)
ЧТО ТАКОЕ РЕАКТИВНОЕ ПРОГРАММИРОВАНИЕ
![Page 8: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/8.jpg)
8
Что такое реактивное программирование?
Реактивное программирование – это парадигма программирования, ориентированная на потоки данных и распространение изменений. (Википедия)
![Page 9: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/9.jpg)
9
Парадигма программирования
Парадигма программирования – это система идей и понятий, определяющих стиль написания компьютерных программ.
![Page 10: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/10.jpg)
10
Императивная программа
var A = 10;var B = A + 1;
// Чему равно В?11
A = A + 1;
// А теперь чему равно В?11
![Page 11: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/11.jpg)
11
Реактивная программаvar A = 10;var B <- A + 1; <- оператор «судьбы»
// Чему равно В?11
A = A + 1;
// А теперь чему равно В?12
![Page 12: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/12.jpg)
12
Реактивное программирование
Реактивное программирование – это парадигма программирования, ориентированная на потоки данных и распространение изменений.
Потоки данных – последовательность значений каждой переменной или свойства класса.
Распространение изменений – уведомления «заинтересованных» об изменениях.
![Page 13: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/13.jpg)
13
PullPull – класс A взаимодействует с классом B и вытягивает из него необходимые данные
Class A Class B
GetData()
Interacts with
![Page 14: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/14.jpg)
14
PushPush – класс B самостоятельно выталкивает данные, как только они становятся доступны.
Class A
ProcessData()
Class BReacts on
![Page 15: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/15.jpg)
15
Примеры из жизни• Вычислимые ячейки Excel
• Принцип Голливуда – «Не звоните нам, мы сами вам позвоним»
• Push - уведомления
![Page 16: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/16.jpg)
РЕАКТИВНОЕ ПРОГРАММИРОВАНИЕ НА C#
![Page 17: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/17.jpg)
17
Прошлое реактивного программирования на C#
• Bindable Linq• https://bindablelinq.codeplex.com• 1.0 beta 1• Последний коммит 5 окт 2008
• Continuous LINQ• http://clinq.codeplex.com/• 2.2.0.1• Последний коммит 23 июня 2010
• Obtics• https://obtics.codeplex.com/• 1.0.13.0• Последний коммит 11 июня 2011
![Page 18: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/18.jpg)
18
Настоящее• Reactive Extensions (Rx)• Эрик Мейер из MS Research
• ReactiveUI• библиотека на базе Rx для создания
элегантных UI для всех XAML платформ
![Page 19: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/19.jpg)
19
Внутри .NETpublic interface IObservable<T>{
IDisposable Subscribe(IObserver<T> observer);}
public interface IObserver<T>{
void OnNext(T value);void OnCompleted();void OnError(Exception error);
}
![Page 20: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/20.jpg)
20
Внутри .NETpublic interface IObservable<T>{
IDisposable Subscribe(IObserver<T> observer);}
public interface IObserver<T>{
void OnNext(T value);void OnCompleted();void OnError(Exception error);
}
![Page 21: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/21.jpg)
21
Внутри .NETpublic interface IObservable<T>{
IDisposable Subscribe(IObserver<T> observer);}
public interface IObserver<T>{
void OnNext(T value);void OnCompleted();void OnError(Exception error);
}
![Page 22: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/22.jpg)
22
Внутри .NETpublic interface IObservable<T>{
IDisposable Subscribe(IObserver<T> observer);}
public interface IObserver<T>{
void OnNext(T value);void OnCompleted();void OnError(Exception error);
}
![Page 23: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/23.jpg)
23
Внутри .NETpublic interface IObservable<T>{
IDisposable Subscribe(IObserver<T> observer);}
public interface IObserver<T>{
void OnNext(T value);void OnCompleted();void OnError(Exception error);
}
![Page 24: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/24.jpg)
24
Оператор судьбы через Rx
var A = new Subject<int>();
// B <- A + 3var B = A.Select(a => a + 3);
// C <- A * Bvar С = A.Zip(B, (a, b) => a * b);
A.OnNext(1);
![Page 25: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/25.jpg)
25
Оператор судьбы через Rx
var A = new Subject<int>();
// B <- A + 3var B = A.Select(a => a + 3);
// C <- A * Bvar С = A.Zip(B, (a, b) => a * b);
A.OnNext(1);
![Page 26: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/26.jpg)
26
Оператор судьбы через Rx
var A = new Subject<int>();
// B <- A + 3var B = A.Select(a => a + 3);
// C <- A * Bvar С = A.Zip(B, (a, b) => a * b);
A.OnNext(1);
![Page 27: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/27.jpg)
27
Observable.Select – проекция
![Page 28: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/28.jpg)
28
Observable.Merge – слияние
![Page 29: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/29.jpg)
29
Observable.Zip - объединение
![Page 30: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/30.jpg)
КАКИЕ ЗАДАЧИ МОЖНО РЕШАТЬ
![Page 31: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/31.jpg)
31
Пример - LoginViewModel
public class LoginViewModel //: INotifyPropertyChanged{ public string Login { get; set; } // PropertyChanged
public string Password { get; set; } // PropertyChanged
public ICommand LoginCommand { get; private set; }
private Task OnLogin() { }}
![Page 32: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/32.jpg)
32
1. Подписка на изменение свойства
// ПодпискаIDisposable _subscription = this.ObservableForProperty(vm => vm.Login) .Subscribe(OnLoginChanged);
// Реакция на событиеprivate void OnLoginChanged (IObservedChange<LoginViewModel, String> change){ }
// Отписка_subscription.Dispose();
![Page 33: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/33.jpg)
33
1. Подписка на изменение свойства
// ПодпискаIDisposable _subscription = this.ObservableForProperty(vm => vm.Login) .Subscribe(OnLoginChanged);
// Реакция на событиеprivate void OnLoginChanged (IObservedChange<LoginViewModel, String> change){ }
// Отписка_subscription.Dispose();
![Page 34: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/34.jpg)
34
1. Подписка на изменение свойства
// ПодпискаIDisposable _subscription = this.ObservableForProperty(vm => vm.Login) .Subscribe(OnLoginChanged);
// Реакция на событиеprivate void OnLoginChanged (IObservedChange<LoginViewModel, String> change){ }
// Отписка_subscription.Dispose();
![Page 35: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/35.jpg)
35
1. Подписка на изменение свойства
// ПодпискаIDisposable _subscription = this.ObservableForProperty(vm => vm.Login) .Subscribe(OnLoginChanged);
// Реакция на событиеprivate void OnLoginChanged (IObservedChange<LoginViewModel, String> change){ }
// Отписка_subscription.Dispose();
![Page 36: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/36.jpg)
36
2. Подписка на изменение нескольких свойств
IDisposable _subscription = this.WhenAny( vm => vm.Login, vn => vm.Password, (login, password) => !string.IsNullOrEmpty(login.Value) && !string.IsNullOrEmpty(password.Value)) .Subscribe(OnCredentialsChanged);
![Page 37: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/37.jpg)
37
2. Подписка на изменение нескольких свойств
IDisposable _subscription = this.WhenAny( vm => vm.Login, vm => vm.Password, (login, password) => !string.IsNullOrEmpty(login.Value) && !string.IsNullOrEmpty(password.Value)) .Subscribe(OnCredentialsChanged);
![Page 38: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/38.jpg)
38
2. Подписка на изменение нескольких свойств
IDisposable _subscription = this.WhenAny( vm => vm.Login, vn => vm.Password, (login, password) => !string.IsNullOrEmpty(login.Value) && !string.IsNullOrEmpty(password.Value)) .Subscribe(OnCredentialsChanged);
![Page 39: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/39.jpg)
39
3. Реактивная асинхронная команда
CanExecute – false, когда1) Не выполняется условие отправки
запроса2) Выполняется асинхронный запрос
![Page 40: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/40.jpg)
40
3. Реактивная асинхронная команда
public LoginViewModel(ILoginService loginService){ _loginService = loginService;
var canExecute = this.WhenAny(vm => vm.Login, vm => vm.Password, (login, password) => !string.IsNullOrEmpty(login.Value) && !string.IsNullOrEmpty(password.Value));
![Page 41: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/41.jpg)
41
3. Реактивная асинхронная команда
public LoginViewModel(ILoginService loginService){ _loginService = loginService;
// Task<bool> Login(login, password)
var canExecute = this.WhenAny(vm => vm.Login, vm => vm.Password, (login, password) => !string.IsNullOrEmpty(login.Value) && !string.IsNullOrEmpty(password.Value));
![Page 42: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/42.jpg)
42
3. Реактивная асинхронная команда
public LoginViewModel(ILoginService loginService){ _loginService = loginService;
var canExecute = this.WhenAny(vm => vm.Login, vm => vm.Password, (login, password) => !string.IsNullOrEmpty(login.Value) && !string.IsNullOrEmpty(password.Value));
![Page 43: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/43.jpg)
43
3. Реактивная асинхронная команда
LoginCommand = ReactiveCommand.CreateAsyncTask (canExecute, async _ => await _loginService.Login(Login, Password));
LoginCommand.Subscribe(OnLoginCompleted);} // of ctor
private void OnLoginCompleted(bool loginSuccessed){ }
![Page 44: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/44.jpg)
44
3. Реактивная асинхронная команда
LoginCommand = ReactiveCommand.CreateAsyncTask (canExecute, async _ => await _loginService.Login(Login, Password));
LoginCommand.Subscribe(OnLoginCompleted);} // of ctor
private void OnLoginCompleted(bool loginSuccessed){ }
![Page 45: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/45.jpg)
45
3. Реактивная асинхронная команда
LoginCommand = ReactiveCommand.CreateAsyncTask (canExecute, async _ => await _loginService.Login(Login, Password));
LoginCommand.Subscribe(OnLoginCompleted);} // of ctor
private void OnLoginCompleted(bool loginSuccessed){ }
![Page 46: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/46.jpg)
46
Достоинства ReactiveCommand
• Не нужно мониторить значения свойств Login и Password
• Не нужно мониторить начало и конец асинхронной операции логина
![Page 47: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/47.jpg)
47
Что ещё умеет ReactiveUI
• Навигация ViewModel First• Маппинг View и ViewModel ручной• IoC на основе Splat • Валидация (не в фреймворке, в сэмплах)• Есть плагин для Fody, который генерит INPC
Но все равно как MVVM фреймворк ReactiveUI слабоват
Поэтому используем из него только команды и привязки
![Page 48: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/48.jpg)
48
Книга мифов о ReactiveUI
![Page 49: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/49.jpg)
49
1. Rx – это экзотическая функциональщина (F#, Scala, Haskel)
F#
Scala
![Page 50: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/50.jpg)
50
На самом деле• Интерфейсы IObservable и
IObserver входят в состав .NET• Для C# существует несколько
библиотек от BindableLinq до ReactiveUI
![Page 51: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/51.jpg)
51
2. Реактивное программирование – это backend
Akka.NET Orleans
ReactiveUI
![Page 52: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/52.jpg)
52
Rx для UI маленький, да удаленький
Что ещё ReactiveUI:• ReactiveCommand• ObservableForProperty• WhenAny
![Page 53: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/53.jpg)
53
3. Боюсь использовать ReactiveUI, слишком экзотично
![Page 54: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/54.jpg)
54
Недостатки ReactiveUI• IoC привязан к Splat• Есть MessageBus, без которого
можно обойтись• Неудобная для WinRT и UWP
навигация ViewModelFirst
![Page 55: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/55.jpg)
55
Используем совместно с другим MVVM
Используем сильные стороны:• ReactiveCommand• Привязки на уровне ViewModel
(ObservableForProperty и WhenAny)
Не используем слабые стороны:• Навигация• IoC
![Page 56: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/56.jpg)
56
4. Использовать несколько MVVM на одном проекте нельзя!
![Page 57: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/57.jpg)
57
Можно, только осторожно
• Каждому MVVM – своя область ответственности
• Контроль, чтобы эта область не расползалась (регулярные ревью)
![Page 58: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/58.jpg)
58
Наш опытReactiveUI Mugen PrismReactiveCommandObservableForPropertyWhenAny
XAML BindingsComposite UI
![Page 59: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/59.jpg)
59
Подведем итоги• ReactiveUI можно (и нужно )
использовать:• Реактивные команды• Привязки на уровне ViewModel вместо
MessageBus• ReactiveUI используем как
дополнение к любимому MVVM фреймворку
![Page 60: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/60.jpg)
60
Реактивное программирование – не страшный и загадочный зверь
![Page 61: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/61.jpg)
61
А верный друг на ваших проектах!
![Page 62: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/62.jpg)
62
Что дальше делать?• Познакомиться: скачать Rx или
ReactiveUI, посмотреть сэмплы• Отладить приложение для
Codefest, сообщество будет вам благодарно
• Попробовать Rx и ReactiveUI на продакшене
![Page 63: Как приручить реактивное программирование](https://reader034.vdocuments.pub/reader034/viewer/2022042619/58d11dd11a28ab2a738b4f23/html5/thumbnails/63.jpg)
63
Полезные ссылкиКлассное видео для начинающихhttps://vimeo.com/43172610
Про Rx для разных языков программированияhttp://reactivex.io/
Официальная страницаhttp://reactiveui.net/Код, примерыhttps://github.com/reactiveuiAutofac https://github.com/alexeyzimarev/RxUI6WithAutofac