Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DI with "Reader Monad"

to4iki
March 26, 2018
1.1k

DI with "Reader Monad"

iOS Test Night #7
2018/03/26
https://github.com/to4iki/Reader

to4iki

March 26, 2018
Tweet

Transcript

  1. ؔ਺Ϟφυ (Input) -> Element ͷϥούʔ struct Reader<Input, Element> { typealias

    WorkFactory = (Input) -> Element private let workFactory: WorkFactory func execute(_ input: Input) -> Element { return workFactory(input) } } 8
  2. map / flatMap func map<T>(_ f: @escaping (Element) -> T)

    -> Reader<Input, T> { return Reader<Input, T> { input in f(self.execute(input)) } } func flatMap<T>(_ f: @escaping (Element) -> Reader<Input, T>) -> Reader<Input, T> { return Reader<Input, T> { input in f(self.execute(input)).execute(input) } } 9
  3. ex. let plusTwoReader = Reader<Int, Int> { $0 + 2

    } let xxxReader = plusTwoReader .map { $0 * 2 } .map { "value is \($0)" } xxxReader.execute(1) // "value is 6" xxxReader.execute(2) // "value is 8" plusTwoReader .flatMap { x in Reader<Int, Int> { y in x * y } } .execute(3) // 18 11
  4. ex. ! protocol UserServiceType { func find(by id: User.Id) ->

    User? } struct UserService: UserServiceType { func find(by id: User.Id) -> User? { ... } } 14
  5. ex. ! Dependency protocol Module { var userService: UserServiceType {

    get } var tweetService: TweetServiceType { get } } 15
  6. ex. ! Client func getTweets(by userId: User.Id) -> Reader<Module, [Tweet]>

    { return Reader { module in module.userService.find(by: userId) .map { $0.name } .map { module.tweetService.findAll(by: $0) } ?? [] } } 16
  7. ex. ! Injection struct ProductionModule: Module { var userService: UserServiceType

    { return UserService.shared } var tweetService: TweetServiceType { return TweetService.shared } } getTweets("prod").execute(ProductionModule()) // [ATweet, BTweet, ...] getTweets("test").execute(MockModule()) // [TestTweet] 17
  8. DI with Reader Monad Pros • ΦϒδΣΫτ୯ҐͰ͸ͳ͘ɺؔ਺୯Ґͷࡉ͔ͳDI͕ग़དྷΔ Cons • ReaderܕʹϩοΫΠϯ͞ΕΔ

    • ೉͍͠ • ґଘ͕ෳ਺ʹͳΔͱѻ͍ʹ͍͘ • Ϟφυ͕ωετͨ࣌͠ͷѻ͍͕৑௕ʹͳΔ 18