Skip to content

Instantly share code, notes, and snippets.

@vani2
Created April 4, 2017 09:19
Show Gist options
  • Select an option

  • Save vani2/33b608ef44ef85e4a7abe663ff9f0b22 to your computer and use it in GitHub Desktop.

Select an option

Save vani2/33b608ef44ef85e4a7abe663ff9f0b22 to your computer and use it in GitHub Desktop.
DAO Presentation Demo
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