Created
November 24, 2020 09:18
-
-
Save donnywals/f62759cf0085639b1fe388613da8fe90 to your computer and use it in GitHub Desktop.
This file contains 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
/* | |
Here's our goal: | |
let localDataStore = UserDataStore() | |
let remoteDataStore = UserApi() | |
let dataStore = CacheBackedDataStore(localDataStore, remoteDataStore) | |
dataStore.fetch(userID) { result in | |
// handle result | |
} | |
*/ | |
protocol LocalStore { | |
associatedtype StoredType | |
func fetch(_ identifier: String) -> StoredType? | |
func persist(_ item: StoredType) | |
} | |
protocol RemoteStore { | |
associatedtype StoredType | |
func fetch(_ identifier: String, _ completion: (StoredType?) -> Void) | |
} | |
struct CacheBackedDataStore<Local: LocalStore, Remote: RemoteStore> where Local.StoredType == Remote.StoredType { | |
let localStore: Local | |
let remoteStore: Remote | |
func fetch(_ identifier: String, completion: @escaping (Remote.StoredType?) -> Void) { | |
if let object = localStore.fetch(identifier) { | |
completion(object) | |
} else { | |
remoteStore.fetch(identifier, { object in | |
if let unwrappedObject = object { | |
localStore.persist(unwrappedObject) | |
} | |
completion(object) | |
}) | |
} | |
} | |
} | |
struct User {} | |
struct Video {} | |
class UserDataStore: LocalStore { | |
var user: User? | |
func fetch(_ identifier: String) -> User? { | |
print("FETCH") | |
return nil | |
} | |
func persist(_ item: User) { | |
print("PERSIST") | |
user = item | |
} | |
} | |
class RemoteUsers: RemoteStore { | |
func fetch(_ identifier: String, _ completion: (User?) -> Void) { | |
print("REMOTE FETCH") | |
completion(User()) | |
} | |
} | |
let local = UserDataStore() | |
let remote = RemoteUsers() | |
class VideosDataStore: LocalStore { | |
func fetch(_ identifier: String) -> Video? { | |
return nil | |
} | |
func persist(_ item: Video) { | |
// | |
} | |
} | |
class RemoteVideos: RemoteStore { | |
func fetch(_ identifier: String, _ completion: (Video?) -> Void) { | |
completion(nil) | |
} | |
} | |
let local2 = VideosDataStore() | |
let remote2 = RemoteVideos() | |
let cacheBacked = CacheBackedDataStore(localStore: local, remoteStore: remote) | |
let cacheBacked2 = CacheBackedDataStore(localStore: local2, remoteStore: remote2) | |
cacheBacked.fetch("1") { user in | |
print("user fetched: \(user)") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment