Александр Сычев "Разделяй и властвуй: CQRS в iOS"
Click here to load reader
Transcript of Александр Сычев "Разделяй и властвуй: CQRS в iOS"
CQRS
Collaboration and staleness
CQRS
CQRS
😈
CQRS
Consistency Availability
Partition tolerance
CQRS
Consistency Availability
Partition tolerance
AP
CQRS
CQRS
CQRS
Presentation layer
Data access layer
Data layer
Business logic layer
CQRS
Presentation layer
Data access layer
Data layer
Business logic layer
SQL
CQRS
Presentation layer
Data access layer
Data layer
Business logic layer
SQL
ManagedObject
CQRS
Presentation layer
Data access layer
Data layer
Business logic layer
SQL
ManagedObject
PlainObject
CQRS
Presentation layer
Data access layer
Data layer
Business logic layer
SQL
ManagedObject
PlainObject
ViewModel
CQRS
Presentation layer
Data assess layer
Data layer
Business logic layer
SQL
ManagedObject
PlainObject
ViewModel
3
CQRS
Presentation layer
Data access layer
Data layer
Business logic layer
ViewModel
ViewModel
ViewModel
ViewModel
CQRS
SELECT * FROM MyViewTable WHERE FolderID = INBOX
CQRS
SELECT * FROM MyViewTable WHERE FolderID = INBOX
In-memory
CQRS
In-memory In-memory
CQRS
key/value store key/value store
CQRS
Queries and Commands
CQRS
Command–query separation B. Meyer
CQRS
1. Queries
2. Commands
CQRS
class User { private(set) var email: String? func isValid(emailAddress: String?) -> Bool { let emailTest = NSPredicate() let isValid = emailTest.evaluate(with: emailAddress) if isValid { email = emailAddress // Command } return isValid // Query } }
CQRS
class User { private(set) var email: String? func isValid(emailAddress: String?) -> Bool { let emailTest = NSPredicate() let isValid = emailTest.evaluate(with: emailAddress) if isValid { email = emailAddress // Command } return isValid // Query } }
CQRS
class User { private(set) var email: String? func isValid(emailAddress: String?) -> Bool { let emailTest = NSPredicate() let isValid = emailTest.evaluate(with: emailAddress) if isValid { email = emailAddress // Command } return isValid // Query } }
CQRS
class User { private(set) var email: String? func isValid(emailAddress: String?) -> Bool { let emailTest = NSPredicate() return emailTest.evaluate(with: emailAddress) } func update(emailAddress: String?) { if isValid(emailAddress: emailAddress) { email = emailAddress } } }
CQRS
Command Query Responsibility Segregation
CQRS
Domain Model
Validation
…
O R M
Presentation
CQRS
Domain Model
Validation
…
Query
Command
Query model
O R M
CQRS
Command•Изменяет состояние системы
•Ничего не возвращает
•Описывает действия пользователей над системой
•Хранит нужные для её выполнения данные
CQRS
Commandclass DeleteUserCommand: Command, DeleteUserContext { private var session: Session init(session: Session) { self.session = session } func execute(context: CommandContext) { session.delete(context) } }
CQRS
Query
•Не изменяет состояние системы
•Хранит нужные для её выполнения данные
•Возвращает результат
CQRS
Queryclass FindUserByIdQuery: Query { private var session: Session init(session: Session) { self.session = session } func ask(context: QueryContext) -> User { return session.query(context) } }
CQRS
MessageService- (void)createDraftMessageWithCompletion:(CompletionBlock)block;
- (void)sendMessage:(Message *)message;
- (Array<Message> *)messagesForFolder:(NSString *)folder;
- (void)obtainAttachment:(Attachment *)attachment completion:(ErrorBlock)block;
CQRS
MessageService- (void)createDraftMessageWithCompletion:(CompletionBlock)block;
- (void)sendMessage:(Message *)message;
- (Array<Message> *)messagesForFolder:(NSString *)folder;
- (void)obtainAttachment:(Attachment *)attachment completion:(ErrorBlock)block;
•- query•- command
CQRS
MessageService
•- query•- command
CreateMessageCommand
SendMessageCommand
ObtainMessagesInFolderQuery
ObtainAttachmentQuery
CQRS
CQRS•Меньше зависимостей в каждом классе
•Соблюдается SRP
•Проще изменять
•Проще тестировать
•Однотипный дизайн кода
CQRS
Domain Model
Validation
…
Query
Command
Query model
O R M
w
r
Event Publisher
CQRS
Event
struct Event { var name: String var payload: [String: AnyObject]? }
DidSendMessage DidCreateDraft
CQRS
Occasionally Connected Clients
CQRS
CQRS
Conference
•Что пойдет не так, если сети нет?
•Как клиент обрабатывает отложенные события?
•Что стоит сделать при появлении сети?
CQRS
Conference
•Пусть клиент продолжает работать
•Нужна очередь отложенных событий
•Синхронизировать данные и сообщить о конфликте
CQRS
Domain Model
Validation
…
Query
Command
Query model
O R M
w
r
Event Publisher
CQRS
Flux
CQRS
CQRS
Выводы
CQRS
Недостатки
•Новый стиль мышления
•Сложность синхронизации
•Overengineering
CQRS
Достоинства
•Высокая производительность чтения
•SRP
•Тестируемость
CQRS
Достоинства
•Высокая производительность чтения
•SRP
•Тестируемость
CQRS
@asychev89
Domain Model
Validation
…
Query
Command
Query model
w
r
Event
O R M