91
Александр Сычев Разработчик iOS Как не выстрелить себе в ногу из конечного автомата

Как не выстрелить себе в ногу из конечного автомата / Александр Сычев (RAMBLER&Co)

  • Upload
    ontico

  • View
    179

  • Download
    5

Embed Size (px)

Citation preview

Page 1: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

Александр Сычев Разработчик iOS

Как не выстрелить себе в ногу из конечного автомата

Page 2: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

• Постановка задачи

• Пример

• Другие реализации

• Заключение

2

Page 3: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine3

• Постановка задачи

• Пример

• Другие реализации

• Заключение

Page 4: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Power OffPower On

Button click

Button click

State

Transition

Event

4

Page 5: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Состояние

5

Page 6: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Состояние

6

Page 7: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine7

•Игровые приложения

•Анализ текстов

•Параллельная обработка запросов

Традиционные задачи

Page 8: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine8

Традиционные задачи

•Игровые приложения

•Анализ текстов

•Параллельная обработка запросов

Page 9: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Page 10: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine10

Традиционные задачи

•Игровые приложения

•Анализ текстов

•Параллельная обработка запросов

Page 11: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine11

Анализ текстов

Pattern: ABABAC

Page 12: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine12

Традиционные задачи

•Игровые приложения

•Анализ текстов

•Параллельная обработка запросов

Page 13: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine13

Обработка запросов

Page 14: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine14

Power OffPower On

Button click

Button click

State

Transition

Event

Page 15: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Presentation layer

Business logic layer

Core layer

Page 16: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Model-View-Controller

16

ModelView

ControllerSends user actions

Updates

Updates

Notifies

Mediator Strategy

Page 17: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

VIPER

17

Page 18: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Model-View-ViewModel

ModelView

ViewModelOwns

Data and user action

Owns and updates

Notifies

UIKit independent

18

Page 19: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Бизнес-логика

19

Page 20: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Бизнес-логика

20

Page 21: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine21

Page 22: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

// обработка данных

22

ViewController

Page 23: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine23

IF (error) { // обработка ошибки } ELSE { // обработка данных }

ViewController

Page 24: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine24

IF (error) { // обработка ошибки } ELSE IF (data != NULL) { // обработка данных } ELSE { // нет данных }

ViewController

Page 25: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine25

IF (isWaiting) { // ждем данные } ELSE IF (error) { // обработка ошибки } ELSE IF (data != NULL) { // обработка данных } ELSE { // нет данных

}

ViewController

Page 26: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

IF (isWaiting) { IF (isWaitingAgain) { // повторное ожидание } ELSE { // ждем данные } } ELSE IF (error) { IF (systemError) { // показать alert } ELSE { // показать toast } } ELSE IF (data != NULL) { IF (data.length < 10) { // обработка данных } ELSE { // обработка данных } } ELSE { // нет данных }

ViewController

26

Page 27: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Недостатки

©💩kod.ru

27

• Нечитабелен

Page 28: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Недостатки• Нечитабелен

• Высокий порог вхождения

• Высокая сложность поддержки и развития

• Негибкий

• Нет защиты от фиктивных состояний

28

Page 29: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Недостатки

29

• Нечитабелен

• Высокий порог вхождения

• Высокая сложность поддержки и развития

• Негибкий

• Нет защиты от фиктивных состояний

Page 30: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Недостатки

30

• Нечитабелен

• Высокий порог вхождения

• Высокая сложность поддержки и развития

• Негибкий

• Нет защиты от фиктивных состояний

Page 31: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Недостатки

31

• Нечитабелен

• Высокий порог вхождения

• Высокая сложность поддержки и развития

• Негибкий

• Нет защиты от фиктивных состояний

Page 32: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine32

Power OffPower On

Button click

Button click

State

Transition

Event

Page 33: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine33

• Постановка задачи

• Пример

• Другие реализации

• Заключение

Page 34: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

GKStateGKStateMachine

34

Page 35: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine35

GKStateGKStateMachine

Page 36: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

GKState

1.class CustomState: GKState

2.func isValidNextState(stateClass: AnyClass) -> Bool

3.func didEnterWithPreviousState(previousState: GKState?)

4.func willExitWithNextState(nextState: GKState)

36

Page 37: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

GKState

1.class CustomState: GKState

2.func isValidNextState(stateClass: AnyClass) -> Bool

3.func didEnterWithPreviousState(previousState: GKState?)

4.func willExitWithNextState(nextState: GKState)

37

Page 38: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

GKState

1.class CustomState: GKState

2.func isValidNextState(stateClass: AnyClass) -> Bool

3.func didEnterWithPreviousState(previousState: GKState?)

4.func willExitWithNextState(nextState: GKState)

38

Page 39: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

GKState

1.class CustomState: GKState

2.func isValidNextState(stateClass: AnyClass) -> Bool

3.func didEnterWithPreviousState(previousState: GKState?)

4.func willExitWithNextState(nextState: GKState)

39

Page 40: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine40

GKStateGKStateMachine

Page 41: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

GKStateMachine

1.init(states states: [GKState])

2.func enterState(_ stateClass: AnyClass) -> Bool

41

Page 42: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

GKStateMachine

1.init(states states: [GKState])

2.func enterState(_ stateClass: AnyClass) -> Bool

42

Page 43: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Опишем состояния и переходы между ними

43

Page 44: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Состояния

Received

Waiting

NoData

Error

44

Page 45: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Состояния

45

Page 46: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Состояния

46

Page 47: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Зададим параметры автомата

47

Page 48: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Создаем состояния

let waitingDataState = WaitingDataState()

let dataAvailableState = DataAvailableState()

let dataNotAvailableState = DataNotAvailableState()

let errorState = ErrorState()

48

Page 49: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Задаем начальное состояние

stateMachine.enterState(WaitingDataState)

49

Page 50: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Управление

50

enterState(WaitingDataState) … IF (error) { enterState(ErrorState) } ELSE IF (data != NULL) { enterState(DataAvailableState) } ELSE { enterState(DataNotAvailableState) }

Page 51: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine51

Gang of Four

Page 52: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

State pattern

52

Page 53: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

GKStateMachine

func goNextWith(_ config: AnyObject)

53

Page 54: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

GKState

func nextStateWith(_ config: AnyObject) -> AnyClass

54

Page 55: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

GameplayKit

Достоинства • стандартная библиотека • проста в освоении • Objective-C / Swift

55

Page 56: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

GameplayKit

Недостатки • доступна с iOS 9.0 • реализации состояний и переходов тесно связаны

• дубликаты состояний

56

Page 57: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine57

• Постановка задачи

• Пример

• Другие реализации

• Заключение

Page 58: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Objective-C

58

Библиотека iOSTransitionKit 998 5.0

Shift 127 5.0?TBStateMachine 36 5.0

Page 59: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Библиотека iOSTransitionKit 998 5.0

Shift 127 5.0?TBStateMachine 36 5.0

Objective-C

59

Page 60: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

TransitionKit

•Состояния отделены от переходов

•Передача полезных данных при переходе

•Описание ошибочных переходов

60

Page 61: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

TransitionKit

61

•Состояния отделены от переходов

•Передача полезных данных при переходе

•Описание ошибочных переходов

Page 62: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

TransitionKit

62

•Состояния отделены от переходов

•Передача полезных данных при переходе

•Описание ошибочных переходов

Page 63: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

RestKit

63

Page 64: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

@interface RKOperationStateMachine : NSObject @property (weak) NSOperation *operation; @property dispatch_queue_t dispatchQueue; @end

@interface RKOperationStateMachine () @property TKStateMachine *stateMachine; @end

RestKit

64

Page 65: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

RestKit

ExecutingReady FinishedStart Finish / Cancel

65

Page 66: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

RestKit

- (void)start { [self.stateMachine start]; }

66

Page 67: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Objective-C

67

Библиотека iOSTransitionKit 998 5.0

Shift 127 5.0?TBStateMachine 36 5.0

Page 68: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Shift

Любой NSObject может быть автоматом

68

Page 69: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Swift

Библиотека Swift version

SwiftState 483 2.2

SwiftyStateMachine 287 2.2

Transporter 232 2.2

69

Page 70: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Библиотека Swift version

SwiftState 483 2.2

SwiftyStateMachine 287 2.2

Transporter 232 2.2

Swift

70

Page 71: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

SwiftyStateMachine

•Полное описание автомата

•Контроль входных сигналов

•Высокая производительность

•Визуализация

71

Page 72: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

SwiftyStateMachine

72

•Полное описание автомата

•Контроль входных сигналов

•Высокая производительность

•Визуализация

Page 73: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

SwiftyStateMachine

73

•Полное описание автомата

•Контроль входных сигналов

•Высокая производительность

•Визуализация

Page 74: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

SwiftyStateMachine

74

•Полное описание автомата

•Контроль входных сигналов

•Высокая производительность

•Визуализация

Page 75: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

SwiftyStateMachine

75

<DOTLabelable>

•Визуализация

Page 76: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine76

• Постановка задачи

• Пример

• Другие реализации

• Заключение

Page 77: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Достоинства• Формализация

• Тестируемость

• Контроль потоков данных

• Контроль ошибок

• Единая точка входа для логирования / статистики

• История операций

77

Page 78: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Достоинства

78

• Формализация

• Тестируемость

• Контроль потоков данных

• Контроль ошибок

• Единая точка входа для логирования / статистики

• История операций

Page 79: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Достоинства

79

• Формализация

• Тестируемость

• Контроль потоков данных

• Контроль ошибок

• Единая точка входа для логирования / статистики

• История операций

Page 80: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Достоинства

80

• Формализация

• Тестируемость

• Контроль потоков данных

• Контроль ошибок

• Единая точка входа для логирования / статистики

• История операций

Page 81: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Достоинства

81

• Формализация

• Тестируемость

• Контроль потоков данных

• Контроль ошибок

• Единая точка входа для логирования / статистики

• История операций

Page 82: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Достоинства

82

• Формализация

• Тестируемость

• Контроль потоков данных

• Контроль ошибок

• Единая точка входа для логирования / статистики

• История операций

Page 83: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

ЗадачиЗаказ такси

83

Page 84: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Задачи- (void)handleOrder:(Order *)order { OrderStatus status = order.status; switch (status) { case OrderStatusOrdering: [self.view showOrdering]; [self.interactor handleRideWithOrder:order]; break; case OrderStatusWaiting: [self.view showWaiting]; [self.interactor handleWaitingWithOrder:order]; break; case OrderStatusDriverIsWaiting: [self.view showDriverIsWaiting]; [self.interactor handleDriverIsWaitingWithOrder:order]; break; case OrderStatusRide: [self.view showRide]; [self.interactor handleRideWithOrder:order]; break; case OrderStatusPayment: [self.view showPayment]; [self.interactor handlePaymentWithOrder:order]; break; case OrderStatusFinished: [self.view showFinished]; [self.interactor handleFinishedWithOrder:order]; break; case OrderStatusWaitingCancelled: [self.view showWaitingCancelled]; [self.interactor handleWaitingCancelledWithOrder:order]; break; case OrderStatusDriverIsWaitingCancelled: [self.view showDriverIsWaitingCancelled]; [self.interactor handleDriverIsWaitingCancelledWithOrder:order]; break; default: [self.view showError]; break; } }

84

Page 85: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Задачи

WaitingOrderingDriver is waiting

Placed

RidePayment

Arrived

Go

ArrivedFinished Paid

Cancelled

Cancelled

85

Заказ такси

Page 86: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Заказ такси

86

Page 87: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

ЗадачиОформление заказа

87

Page 88: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

Задачи

DrawingUpOrdering Payment

Confirm

ShippingReceipt

Approved

Paid

ArrivedFinished

Received

Cancelled

Cancelled

88

Оформление заказа

Page 89: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

ЗадачиОплата

89

Page 90: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

App Coordinators

90

Page 91: Как не выстрелить себе в ногу из конечного автомата /  Александр Сычев (RAMBLER&Co)

iOS state machine

@sychevbrain89

Brain89

[email protected] www.rambler-co.ru/jobs

Power OffPower On

Button click

Button click

State

Transition

Event