Отличия личностно-ориентированной и занания-ориентированной модели школы
"REST-SOA-View-Controller или Проектирование...
Transcript of "REST-SOA-View-Controller или Проектирование...
REST-SOA-Controller-View: Проектирование обмена данными
Егор Тафланиди19/03/[email protected]
Агенда
- Опрос аудитории
- Слои
- Сервер
- Протокол
- Мобильное приложение
- Пример
01
02
Опрос аудитории
03
Польза
Агенда
- Опрос аудитории
- Слои
- Сервер
- Протокол
- Мобильное приложение
- Пример
04
Агенда
- Опрос аудитории
- Слои
- Сервер
- Протокол
- Мобильное приложение
- Пример
04
- Domain-Specific Language
- DSL-интерфейс
- Обмен модельными объектами
Слои
05
СВОЙСТВА
Entity• id { get set }
/* no logic */
Агенда
- Опрос аудитории
- Слои
- Сервер
- Протокол
- Мобильное приложение
- Пример
06
Entity• id { get set }!
- База данных
Сервер
07
СТРУКТУРА
Table: Userid name surname1 Иван Иванов2 Сидор Сидоров
- База данных
Сервер
07
СТРУКТУРА
Table: Username surnameИван ИвановСидор Сидоров
id12
- База данных
Сервер
08
СТРУКТУРА
Table: Username surnameИван ИвановСидор Сидоров
id12
=>
User• id • name • surname
- ORM вычитывает объект из базы
- DAO транслирует ORM-объект в POJO
Сервер
09
СТРУКТУРА: ПУТЕШЕСТВИЕ ENTITY
User• id • name • surname
ORMDatabase DAO
ORM Object
BusinessLogic
Object
Сервер
10
User• id • name • surname
BusinessLogic Serialiser
Object
Transport
DT Object
- ORM вычитывает объект из базы
- DAO транслирует ORM-объект в POJO
- Бизнес-логика транслирует POJO в DTO
СТРУКТУРА: ПУТЕШЕСТВИЕ ENTITY
Сервер
11
User• id • name • surname
Transport HTTP
JSON
MobileApp
JSON
…
- ORM вычитывает объект из базы
- DAO транслирует ORM-объект в POJO
- Бизнес-логика транслирует POJO в DTO
- Транспорт транслирует DTO в JSON
- JSON передаётся на фронт
СТРУКТУРА: ПУТЕШЕСТВИЕ ENTITY
Сервер
12
СТРУКТУРА: TYPE STACK
User
ORMDatabase
DAO
BusinessLogic
Serialiser
Transport
…
Product
ORMDatabase
DAO
BusinessLogic
Serialiser
Transport
…
Message
ORMDatabase
DAO
BusinessLogic
Serialiser
Transport
…
…
Сервер
13
СЕРВИСЫ
User
Product
Message
} НаборWeb-сервисов
14
ПротоколREST
Протокол
15
RESOURCE
Resource R is a temporally varying membership
function MR(t), which for time t
maps to a set of entities
/ Representational State Transfer, dissertation /http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm
Протокол
16
ENTITY & URL ENDPOINT
/entities(resource)
Array(Entity)
Entity• id { get set }
Протокол
16
ENTITY & WEB SERVICE
: REntity
POST /entities
GET /entities
GET /entities/{id}
PATCH /entities/{id}
DELETE /entities/{id}
/entities(resource)
Entity• id { get set }
Протокол
17
C.R.U.D.
POST /entities
GET /entities
GET /entities/{id}
PATCH /entities/{id}
DELETE /entities/{id}
Create
Read
Update
Delete
Entity• id { get set }∀
Протокол
18
ВЛОЖЕННОСТЬ. ДОВЕРИЕ К СЕРВЕРУ
User• id: Long • name: String
PATCH /users/{id}/nameUser• id: Long • name: String
/* name patched */
Агенда
- Опрос аудитории
- Слои
- Сервер
- Протокол
- Мобильное приложение
- Пример
19
20
Мобильное приложениеSDK MVC
Мобильное приложение
- Тип данных = ключевая сущность
- Разница в логике = набор полей
21
SERVICE-ORIENTED ARCHITECTURE
Entity
ORMDatabase
DAO
BusinessLogic
Serialiser
Transport
…
22
Мобильное приложениеSERVICE-ORIENTED ARCHITECTURE
SERVICE
22
SERVICE
TRANSPORT
Мобильное приложениеSERVICE-ORIENTED ARCHITECTURE
22
SERVICE
TRANSPORT
SERIALIZERPARSER
Мобильное приложениеSERVICE-ORIENTED ARCHITECTURE
22
SERVICE
TRANSPORT
SERIALIZERPARSER
Мобильное приложениеSERVICE-ORIENTED ARCHITECTURE
22
SERVICE
DATABASE
Мобильное приложениеSERVICE-ORIENTED ARCHITECTURE
DAO
22
Мобильное приложениеSERVICE-ORIENTED ARCHITECTURE
SERVICESERVICE SERVICE
22
SERVICESERVICE SERVICE
SERVICE LAYER
Мобильное приложениеSERVICE-ORIENTED ARCHITECTURE
22
SERVICESERVICE SERVICE
SERVICE LAYER
Мобильное приложениеSERVICE-ORIENTED ARCHITECTURE
CONTROLLER
23
Интерлюдия: многопоточностьCALLBACK HELL
Callback Hell
24
24
T1
T2
T3
T4
Callback Hell
24
T1
T2
T3
T4
CONTROLLER
Callback Hell
24
T1
T2
T3
T4
CONTROLLER SERVICE
Callback Hell
24
T1
T2
T3
T4
CONTROLLER SERVICE SERIALIZER
Callback Hell
24
T1
T2
T3
T4
CONTROLLER SERVICE SERIALIZER SERVICE
Callback Hell
24
T1
T2
T3
T4
CONTROLLER SERVICE SERIALIZER SERVICE TRANSPORT
Callback Hell
24
T2
T1
T3
T4
CONTROLLER SERVICE SERIALIZER SERVICE TRANSPORT
Callback Hell
24
T2
T1
T3
T4
CONTROLLER SERVICE SERIALIZER SERVICE TRANSPORT PARSER
Callback Hell
24
T2
T1
T3
T4
CONTROLLER SERVICE SERIALIZER SERVICE TRANSPORT PARSER
Callback Hell
24
T2
T1
T3
T4
CONTROLLER SERVICE SERIALIZER SERVICE TRANSPORT DBPARSER
Callback Hell
24
T2
T1
T3
T4
CONTROLLER SERVICE SERIALIZER SERVICE TRANSPORT DBPARSER
Callback Hell
24
T2
T1
T3
T4
CONTROLLER SERVICE SERIALIZER SERVICE TRANSPORT …PARSER DB
Callback Hell
24
T2
T1
T3
T4
SERVICE TRANSPORT PARSER DBSERVICE SERVICE SERVICE
Callback Hell
24
T2
T1
T3
T4
SERVICE TRANSPORT PARSER DBSERVICE SERVICE SERVICE
RESULT
Callback Hell
24
T2
T1
SERVICE PARSERSERVICE SERVICE DB SERVICE …TRANSPORT
Callback Hell
24
T2
T1
SERVICE PARSERSERVICE SERVICE DB SERVICE …TRANSPORT
OPERATION
Callback Hell
Operation
25
id result = transport.obtain(parameters)
id object = parser.parse(result)
db.save(object)
return object
Operation
26
dispatch_async(background_queue, ^{
id result = transport.obtain(parameters)
id object = parser.parse(result)
db.save(object)
dispatch_async(main_queue, ^{
completionBlock(object)
})
})
Operation
27
– (void)main {
id result = transport.obtain(parameters)
id object = parser.parse(result)
db.save(object)
completionBlock(object)
}
@interface Operation : NSOperation…@implementation Operation
Агенда
- Опрос аудитории
- Слои
- Сервер
- Протокол
- Мобильное приложение
- Пример
28
00
ПримерSERVICE LAYER
01
Transport
02
Transport
- CRUD ~ URL endpoint + HTTP method + parameters
- ~ Web service base URL
- Семафор в качестве «выпрямителя» потоков
SYNCHRONOUS
03
/**Операция«Получитьколлекциюсущностей».Пример:
GEThttp://api.customer.com/v1/entitites$headers
@paramparameters-параметрызапроса.@seeTransportationParameters
@returnВозвращаетрезультатвыполненияоперации.*/-(TransportationResult*)obtainAllWithParameters:(TransportationParameters*)parameters;
TransportSYNCHRONOUS
03
/**Операция«Обновитьзначениесвойствасущности».Пример:
PATCHhttp://api.customer.com/v1/entitites/{entityId}/{property}$headers{$body_parameters}
@paramentityId-идентификаторсущности;@paramproperty-названиесвойствасущности;@paramparameters-параметрызапроса.@seeTransportationParameters
@returnВозвращаетрезультатвыполненияоперации.*/
-(TransportationResult*)updateWithId:(NSString*)entityIdproperty:(NSString*)propertyparameters:(TransportationParameters*)parameters;
TransportSYNCHRONOUS
04
Parser
05
Parser
- Наличие объекта = наличие всех его обязательных полей
- Для пользователя ошибки «парсер не смог распознать данные» и «данные не пришли» будут иметь одинаковые последствия
- Не стоит городить непробиваемую «оборону»
- Приложению нужны объекты, а не топология
BLIND
06
ParserBLIND
@interfaceParser<__covariantEntity>:NSObject-(NSArray*)parseAll:(id)json;
-(BOOL)parsable:(NSDictionary*)json;-(Class)objectClass;-(NSDictionary*)mapping;-(Entity)sanitize:(Entity)object;-(Entity)fulfill:(Entity)objectfrom:(NSDictionary*)json;@end
07
ParserEXAMPLE{"id":1,"dict":{"id":"3","text":"annotation"},"array":[{"id":4,"text":"description","note":"FYI"}]}
Entity• id • text • note
08
ParserEXAMPLE
@interfaceParser<__covariantEntity>:NSObject-(NSArray*)parseAll:(id)json;
-(BOOL)parsable:(NSDictionary*)json;-(Class)objectClass;-(NSDictionary*)mapping;-(Entity)sanitize:(Entity)object;-(Entity)fulfill:(Entity)objectfrom:(NSDictionary*)json;@end
– parseAll:
09
ParserEXAMPLE{"id":1,"dict":{"id":"3","text":"annotation"},"array":[{"id":4,"text":"description","note":"FYI"}]}
– parseAll:
10
ParserEXAMPLE{"id":1,"dict":{"id":"3","text":"annotation"},"array":[{"id":4,"text":"description","note":"FYI"}]}
11
ParserEXAMPLE
@interfaceParser<__covariantEntity>:NSObject-(NSArray*)parseAll:(id)json;
-(BOOL)parsable:(NSDictionary*)json;-(Class)objectClass;-(NSDictionary*)mapping;-(Entity)sanitize:(Entity)object;-(Entity)fulfill:(Entity)objectfrom:(NSDictionary*)json;@end
– parseable:
12
ParserEXAMPLE{"id":1,"dict":{"id":"3","text":"annotation"},"array":[{"id":4,"text":"description","note":"FYI"}]}
– parseable:
12
ParserEXAMPLE{"id":1,"dict":{"id":"3","text":"annotation"},"array":[{"id":4,"text":"description","note":"FYI"}]}
– parseable:
12
ParserEXAMPLE{"id":1,"dict":{"id":"3","text":"annotation"},"array":[{"id":4,"text":"description","note":"FYI"}]}
– parseAll:
12
ParserEXAMPLE{"id":1,"dict":{"id":"3","text":"annotation"},"array":[{"id":4,"text":"description","note":"FYI"}]}
– parseAll:
12
ParserEXAMPLE{"id":1,"dict":{"id":"3","text":"annotation"},"array":[{"id":4,"text":"description","note":"FYI"}]}
12
ParserEXAMPLE{"id":1,"dict":{"id":"3","text":"annotation"},"array":[{"id":4,"text":"description","note":"FYI"}]}
– parseAll:
12
ParserEXAMPLE{"id":1,"dict":{"id":"3","text":"annotation"},"array":[{"id":4,"text":"description","note":"FYI"}]}
– parseAll:
12
ParserEXAMPLE{"id":1,"dict":{"id":"3","text":"annotation"},"array":[{"id":4,"text":"description","note":"FYI"}]}
– parseable:
12
ParserEXAMPLE{"id":1,"dict":{"id":"3","text":"annotation"},"array":[{"id":4,"text":"description","note":"FYI"}]}
– parseable:
13
ParserEXAMPLE
@interfaceParser<__covariantEntity>:NSObject-(NSArray*)parseAll:(id)json;
-(BOOL)parsable:(NSDictionary*)json;-(Class)objectClass;-(NSDictionary*)mapping;-(Entity)sanitize:(Entity)object;-(Entity)fulfill:(Entity)objectfrom:(NSDictionary*)json;@end
14
ParserEXAMPLE{"id":1,"dict":{"id":"3","text":"annotation"},"array":[{"id":4,"text":"description","note":"FYI"}]}
– parseable:Entity• id = "3" • text = "annotation" • note = nil
14
ParserEXAMPLE{"id":1,"dict":{"id":"3","text":"annotation"},"array":[{"id":4,"text":"description","note":"FYI"}]}
Entity• id = "3" • text = "annotation" • note = nil
– sanitize:
14
ParserEXAMPLE{"id":1,"dict":{"id":"3","text":"annotation"},"array":[{"id":4,"text":"description","note":"FYI"}]}
Entity• id = "3" • text = "annotation" • note = nil
– sanitize:
14
ParserEXAMPLE{"id":1,"dict":{"id":"3","text":"annotation"},"array":[{"id":4,"text":"description","note":"FYI"}]}
Entity• id = 3 • text = "annotation" • note = nil
– sanitize:
14
ParserEXAMPLE{"id":1,"dict":{"id":"3","text":"annotation"},"array":[{"id":4,"text":"description","note":"FYI"}]}
Entity• id = 3 • text = "annotation" • note = nil
– fulfill:
– parseAll:
15
ParserEXAMPLE{"id":1,"dict":{"id":"3","text":"annotation"},"array":[{"id":4,"text":"description","note":"FYI"}]}
– parseAll:
15
ParserEXAMPLE{"id":1,"dict":{"id":"3","text":"annotation"},"array":[{"id":4,"text":"description","note":"FYI"}]}
15
ParserEXAMPLE{"id":1,"dict":{"id":"3","text":"annotation"},"array":[{"id":4,"text":"description","note":"FYI"}]}
– parseAll:
15
ParserEXAMPLE{"id":1,"dict":{"id":"3","text":"annotation"},"array":[{"id":4,"text":"description","note":"FYI"}]}
15
ParserEXAMPLE{"id":1,"dict":{"id":"3","text":"annotation"},"array":[{"id":4,"text":"description","note":"FYI"}]}
=> [Entity]
16
DAOШАБЛОН ПРОЕКТИРОВАНИЯ
17
DAO
- Взаимодействие с DAO посредством модельных объектов (Entity : NSObject) => изоляция
- Инжектируемость- Потокобезопасность
- «Соединение» с базой данных- Транзакционность
ИДЕОЛОГИЯ
18
DAO
- persist(Entity) -> BOOL
- persistAll(Array<Entity>) -> BOOL
- read(ID) -> Entity
- readAll() -> Array<Entity>
- erase(ID) -> BOOL
- eraseAll() -> BOOL
ИНТЕРФЕЙС
19
Entity TranslatorШАБЛОН ПРОЕКТИРОВАНИЯ
20
Entity Translator
Entity• id • text • note
=><=
{"id":4,"text":"description","note":"FYI"}
EntityDTO : NSDictionary
20
Entity Translator
Entity• id • text • note
=><=
ORMEntity• id • text • note
21
DAO TRANSLATOREntity Translator
@interfaceRealmTranslator:NSObject
-(RLMEntry*)toEntry:(id<Persistable>)entity;
-(id<Persistable>)toEntity:(RLMEntry*)entry;
-(NSString*)entryClass;
@end
22
DAO TRANSLATOREntity Translator
{
letdao:DAO=RealmDAO(translator:translator)
}
23
Entity TranslatorКОДОГЕНЕРАЦИЯ
24
Entity TranslatorКОДОГЕНЕРАЦИЯ
/**Последняятранзакция.
@jsonlast_transaction@mandatory@realmlastTransaction*/@property(…)Transaction*lastTransaction;
25
Service
26
Service
- Инстанциирование утилит (?)
- Набор виртуальных конструкторов
- Координация данных между утилитами
- Многопоточность, инстанциирование операций
- Асинхронный интерфейс для верхнего слоя UI
ОТВЕТСТВЕННОСТЬ
27
Service LayerИНВЕРТЕР ЗАВИСИМОСТЕЙ
28
Service Layer
- Инстанциирование сервисов
- Инжектирование сервисов
- Инжектирование очередей запросов
ОТВЕТСТВЕННОСТЬ
Итоги
- REST
- SOA
- Многопоточность = зло
- Пример реализации сервисного уровня
ВОПРОСЫ ЕСТЬ?ВОПРОСОВ НЕТ!
Егор Тафланиди[email protected]