Created
April 4, 2017 09:19
-
-
Save vani2/33b608ef44ef85e4a7abe663ff9f0b22 to your computer and use it in GitHub Desktop.
DAO Presentation Demo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import UIKit | |
| // MARK: - Сущность БД | |
| class Entry { | |
| let entryId: String | |
| init(id: String) { | |
| entryId = id | |
| } | |
| } | |
| // MARK: - Сущность | |
| class Entity { | |
| let entityId: String | |
| init(id: String) { | |
| entityId = id | |
| } | |
| } | |
| // MARK: - Объект БД | |
| struct MockDataBase { | |
| func create(_ entry: Entry) {} | |
| func create(_ entries: [Entry]) {} | |
| func read(type: Entry.Type, entryId: String) -> Entry? { | |
| return nil | |
| } | |
| func read(type: Entry.Type) -> [Entry] { | |
| return [Entry]() | |
| } | |
| func delete(type: Entry.Type, entryId: String) {} | |
| func delete(type: Entry.Type) {} | |
| func save() -> Bool { return true } | |
| func rollback() {} | |
| } | |
| // MARK: - Транслятор | |
| class Translator { | |
| let entryType: Entry.Type | |
| let entityType: Entity.Type | |
| init(entryType: Entry.Type, entityType: Entity.Type) { | |
| self.entityType = entityType | |
| self.entryType = entryType | |
| } | |
| func toEntry(_ entity: Entity) -> Entry { | |
| return Entry(id: entity.entityId) | |
| } | |
| func toEntries(_ entities: [Entity]) -> [Entry] { | |
| return entities.map { self.toEntry($0) } | |
| } | |
| func toEntity(_ entry: Entry) -> Entity { | |
| return Entity(id: entry.entryId) | |
| } | |
| func toEntities(_ entries: [Entry]) -> [Entity] { | |
| return entries.map { self.toEntity($0) } | |
| } | |
| } | |
| // MARK: - DAO | |
| struct MockDAO { | |
| private let dataBase = MockDataBase() | |
| private let translator: Translator | |
| // MARK: - Init | |
| init(translator: Translator) { | |
| self.translator = translator | |
| } | |
| // MARK: - Public | |
| func persist(_ entity: Entity) -> Bool { | |
| if let entry = dataBase.read(type: translator.entryType, entryId: entity.entityId) { | |
| dataBase.delete(type: translator.entryType, entryId: entry.entryId) | |
| } | |
| dataBase.create(translator.toEntry(entity)) | |
| return saveOrRollback() | |
| } | |
| func persist(_ entities: [Entity]) -> Bool { | |
| entities | |
| .flatMap { self.dataBase.read(type: self.translator.entryType, entryId: $0.entityId) } | |
| .forEach { self.dataBase.delete(type: self.translator.entryType, entryId: $0.entryId) } | |
| dataBase.create(translator.toEntries(entities)) | |
| return saveOrRollback() | |
| } | |
| func read(id: String) -> Entity? { | |
| if let entry = dataBase.read(type: translator.entryType, entryId: id) { | |
| return translator.toEntity(entry) | |
| } else { | |
| return nil | |
| } | |
| } | |
| func read() -> [Entity] { | |
| return translator.toEntities(dataBase.read(type: translator.entryType)) | |
| } | |
| func erase(id: String) -> Bool { | |
| dataBase.delete(type: translator.entryType, entryId: id) | |
| return saveOrRollback() | |
| } | |
| func erase() -> Bool { | |
| dataBase.delete(type: translator.entryType) | |
| return saveOrRollback() | |
| } | |
| // MARK: - Private | |
| private func saveOrRollback() -> Bool { | |
| let result = dataBase.save() | |
| if !result { | |
| dataBase.rollback() | |
| } | |
| return result | |
| } | |
| } | |
| /*: | |
| 1. Получаете JSON от сервера | |
| 2. Создаете Entity | |
| 3. Вызываете DAO | |
| */ | |
| class User: Entity { | |
| let name: String | |
| init(id: String, name: String) { | |
| self.name = name | |
| super.init(id: id) | |
| } | |
| } | |
| class DBUser: Entry { | |
| let name: String | |
| init(id: String, name: String) { | |
| self.name = name | |
| super.init(id: id) | |
| } | |
| } | |
| class UserTranslator: Translator { | |
| override func toEntity(_ entry: Entry) -> Entity { | |
| return User(id: entry.entryId, name: (entry as! DBUser).name) // как сделать без приведения типов??? | |
| } | |
| override func toEntry(_ entity: Entity) -> Entry { | |
| return DBUser(id: entity.entityId, name: (entity as! User).name) | |
| } | |
| } | |
| // Базовый сервис | |
| class Service {} | |
| class UsersService: Service { | |
| private let dao = MockDAO(translator: Translator(entryType: DBUser.self, entityType: User.self)) | |
| func obtainFromNetwork() -> [User] { | |
| let users = [User]() //не пустой | |
| if !dao.persist(users) { | |
| //обработка ошибки или ничего не делаем | |
| } | |
| return users | |
| } | |
| func obtainFromCache() -> [User] { | |
| return dao.read() as! [User] | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment