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

Preview:

Citation preview

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

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

iOS state machine

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

• Пример

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

• Заключение

2

iOS state machine3

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

• Пример

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

• Заключение

iOS state machine

Power OffPower On

Button click

Button click

State

Transition

Event

4

iOS state machine

Состояние

5

iOS state machine

Состояние

6

iOS state machine7

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

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

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

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

iOS state machine8

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

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

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

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

iOS state machine

iOS state machine10

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

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

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

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

iOS state machine11

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

Pattern: ABABAC

iOS state machine12

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

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

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

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

iOS state machine13

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

iOS state machine14

Power OffPower On

Button click

Button click

State

Transition

Event

iOS state machine

Presentation layer

Business logic layer

Core layer

iOS state machine

Model-View-Controller

16

ModelView

ControllerSends user actions

Updates

Updates

Notifies

Mediator Strategy

iOS state machine

VIPER

17

iOS state machine

Model-View-ViewModel

ModelView

ViewModelOwns

Data and user action

Owns and updates

Notifies

UIKit independent

18

iOS state machine

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

19

iOS state machine

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

20

iOS state machine21

iOS state machine

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

22

ViewController

iOS state machine23

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

ViewController

iOS state machine24

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

ViewController

iOS state machine25

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

}

ViewController

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

iOS state machine

Недостатки

©💩kod.ru

27

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

iOS state machine

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

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

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

• Негибкий

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

28

iOS state machine

Недостатки

29

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

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

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

• Негибкий

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

iOS state machine

Недостатки

30

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

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

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

• Негибкий

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

iOS state machine

Недостатки

31

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

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

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

• Негибкий

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

iOS state machine32

Power OffPower On

Button click

Button click

State

Transition

Event

iOS state machine33

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

• Пример

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

• Заключение

iOS state machine

GKStateGKStateMachine

34

iOS state machine35

GKStateGKStateMachine

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

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

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

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

iOS state machine40

GKStateGKStateMachine

iOS state machine

GKStateMachine

1.init(states states: [GKState])

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

41

iOS state machine

GKStateMachine

1.init(states states: [GKState])

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

42

iOS state machine

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

43

iOS state machine

Состояния

Received

Waiting

NoData

Error

44

iOS state machine

Состояния

45

iOS state machine

Состояния

46

iOS state machine

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

47

iOS state machine

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

let waitingDataState = WaitingDataState()

let dataAvailableState = DataAvailableState()

let dataNotAvailableState = DataNotAvailableState()

let errorState = ErrorState()

48

iOS state machine

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

stateMachine.enterState(WaitingDataState)

49

iOS state machine

Управление

50

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

iOS state machine51

Gang of Four

iOS state machine

State pattern

52

iOS state machine

GKStateMachine

func goNextWith(_ config: AnyObject)

53

iOS state machine

GKState

func nextStateWith(_ config: AnyObject) -> AnyClass

54

iOS state machine

GameplayKit

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

55

iOS state machine

GameplayKit

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

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

56

iOS state machine57

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

• Пример

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

• Заключение

iOS state machine

Objective-C

58

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

Shift 127 5.0?TBStateMachine 36 5.0

iOS state machine

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

Shift 127 5.0?TBStateMachine 36 5.0

Objective-C

59

iOS state machine

TransitionKit

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

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

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

60

iOS state machine

TransitionKit

61

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

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

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

iOS state machine

TransitionKit

62

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

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

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

iOS state machine

RestKit

63

iOS state machine

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

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

RestKit

64

iOS state machine

RestKit

ExecutingReady FinishedStart Finish / Cancel

65

iOS state machine

RestKit

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

66

iOS state machine

Objective-C

67

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

Shift 127 5.0?TBStateMachine 36 5.0

iOS state machine

Shift

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

68

iOS state machine

Swift

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

SwiftState 483 2.2

SwiftyStateMachine 287 2.2

Transporter 232 2.2

69

iOS state machine

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

SwiftState 483 2.2

SwiftyStateMachine 287 2.2

Transporter 232 2.2

Swift

70

iOS state machine

SwiftyStateMachine

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

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

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

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

71

iOS state machine

SwiftyStateMachine

72

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

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

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

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

iOS state machine

SwiftyStateMachine

73

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

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

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

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

iOS state machine

SwiftyStateMachine

74

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

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

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

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

iOS state machine

SwiftyStateMachine

75

<DOTLabelable>

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

iOS state machine76

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

• Пример

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

• Заключение

iOS state machine

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

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

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

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

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

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

77

iOS state machine

Достоинства

78

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

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

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

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

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

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

iOS state machine

Достоинства

79

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

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

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

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

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

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

iOS state machine

Достоинства

80

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

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

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

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

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

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

iOS state machine

Достоинства

81

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

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

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

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

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

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

iOS state machine

Достоинства

82

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

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

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

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

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

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

iOS state machine

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

83

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

iOS state machine

Задачи

WaitingOrderingDriver is waiting

Placed

RidePayment

Arrived

Go

ArrivedFinished Paid

Cancelled

Cancelled

85

Заказ такси

iOS state machine

Заказ такси

86

iOS state machine

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

87

iOS state machine

Задачи

DrawingUpOrdering Payment

Confirm

ShippingReceipt

Approved

Paid

ArrivedFinished

Received

Cancelled

Cancelled

88

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

iOS state machine

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

89

iOS state machine

App Coordinators

90

iOS state machine

@sychevbrain89

Brain89

rambler-ioshr@rambler-co.ru www.rambler-co.ru/jobs

Power OffPower On

Button click

Button click

State

Transition

Event

Recommended