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

なぜうちのチームは開発中のアプリを 
MVVM から MVC に戻したのか

Elvis Shi
December 12, 2018

なぜうちのチームは開発中のアプリを 
MVVM から MVC に戻したのか

Elvis Shi

December 12, 2018
Tweet

More Decks by Elvis Shi

Other Decks in Programming

Transcript

  1. } var employedBy = "YUMEMI Inc." var job = "iOS

    Developer" var favoriteLanguage = "Swift" var twitter = "@lovee" var qiita = "lovee" var github = "el-hoshino" var additionalInfo = """ εϊϘָ͍͠ """ class Me: Developable, Talkable {
  2. 
 1. ࠓ౓ͷΞϓϦɺϦΞϧλΠϜͷϨʔτมಈΛදࣔ ͠ͳ͍ͱߦ͚ͳ͍͠ɺ"OESPJE͸࣮࣭.77. ͷ""$࢖͏͔ΒɺJ04΋ʢ3YΛ࢖ͬͨσʔλ όΠϯσΟϯά͕͋Δʣ.77.Ͱ࡞Ζ͏͔ʁ 
 ๻ Ͳ͔ͬͪͱ͍͏ͱ.7$ͷํʹ׳Ε͍ͯΔͷͰɺ εέδϡʔϧΩοπΩπͩ͠ɺ࢖͍׳ΕͯΔ.7$

    ͷํ͕ແ೉͔ͱʜ $ 
 5. ࠷ۙ͸.77.ͷํ͕τϨϯυͬΆ͍ؾ͕͢Δ͠ɺ ࢲͨͪ΋.77.΍Γ͍ͨͰ͢ʂ 
 ๻ ͏ʔΜΈΜͳ͕ͦ͏ݴ͏ͷͳΒ͡Ό͋.77.Ͱ ߦ͜͏͔ $ 
 5. ͱݴ͏Θ͚Ͱ.77.ͱ3Y4XJGU͋Μ·Γৄ͠ ͘ͳ͍ͷͰ佃Ꭺ͓ئ͍͠·͢ʂ 
 ๻ ͓͍ɺϚδ͔
  3. λΠϜϥΠϯ ݄ ݄ ݄ ݄ ݄ ݄ ݄ ݄ ΞϓϦ։ൃ։࢝


    ʢ.77.ܾఆʣ αʔό"1*
 શͯଗ͏ ݁߹ςετ डೖςετ ഑৴։࢝ 䘦 ㌓
  4. λΠϜϥΠϯ ΞϓϦ։ൃ։࢝
 ʢ.77.ܾఆʣ ݄ ݄ ݄ ݄ ݄ ݄ ݄

    αʔό"1*
 Ұ෦ଗ͑ͣ ݄ ๏վਖ਼૝ఆ
 ʢը໘࢓༷Ұ෦มߋʣ "1*࣮Ϩεϙϯε
 ఆٛॻͱ૬ҧΛൃ֮ ݪଇ.7$ʹ
 ํ޲స׵ܾఆ Ұ୴։ൃऴྃ༧ఆ 䘞 ⶿
  5. ࣮ࡍ.77.ʢʷ3Y4XJGUʣͰ։ൃͯ͠Έͨײ૝ ʢωΨςΟϒʣ w 7JFX$POUSPMMFSͱ7JFX.PEFM͕େྔͷॏෳఆٛ w ॳظ࣮૷ίετ͕ߴ͍ w ը໘࢓༷ͷมߋʹର͢Δमਖ਼ίετ΋ߴ͍ w 3Y4XJGUͷ૒ํ޲όΠσΟϯάͱ0QFSBUPS͕͔ͳΓَ໳

    w ׳Εͯͳ͍ਓʹͱͬͯͷशಘίετ͕ඇৗʹߴ͍ w 13ͷࠩ͠໭͠΋ଟ͍ w 3Y4XJGUͷ0QFSBUPSΛόϦόϦ࢖ͬͨॻ͖ํ͕ಡΈʹ͍͘ w Ͳ͜ʹͲΜͳॲཧ͕Ͳ͏࣮૷͞Ε͍ͯΔͷׂ͔͕ͱ୳͠ʹ͍͘ w େྔͷ.disposed(by: disposeBag)͕໨োΓ
  6. 
 1. ࠓ౓ͷΞϓϦɺϦΞϧλΠϜͷϨʔτมಈΛදࣔ ͠ͳ͍ͱߦ͚ͳ͍͠ɺ"OESPJE͸࣮࣭.77. ͷ""$࢖͏͔ΒɺJ04΋ʢ3YΛ࢖ͬͨσʔλ όΠϯσΟϯά͕͋Δʣ.77.Ͱ࡞Ζ͏͔ʁ 
 ๻ Ͳ͔ͬͪͱ͍͏ͱ.7$ͷํʹ׳Ε͍ͯΔͷͰɺ εέδϡʔϧΩοπΩπͩ͠ɺ࢖͍׳ΕͯΔ.7$

    ͷํ͕ແ೉͔ͱʜ $ 
 5. ࠷ۙ͸.77.ͷํ͕τϨϯυͬΆ͍ؾ͕͢Δ͠ɺ ࢲͨͪ΋.77.΍Γ͍ͨͰ͢ʂ 
 ๻ ͏ʔΜΈΜͳ͕ͦ͏ݴ͏ͷͳΒ͡Ό͋.77.Ͱ ߦ͜͏͔ $ 
 5. ͱݴ͏Θ͚Ͱ.77.ͱ3Y4XJGU͋Μ·Γৄ͠ ͘ͳ͍ͷͰ佃Ꭺ͓ئ͍͠·͢ʂ 
 ๻ ͓͍ɺϚδ͔
  7. .77. // ViewController viewModel.mailPlaceHolderText .asDriver(onErrorJustReturn: "") .drive(rx.mailPlaceHolderText) .disposed(by: disposeBag) mailTextField.rx.text.orEmpty

    .bind(to: viewModel.emailObserver) .disposed(by: disposeBag) loginButton.rx.tap .bind(to: viewModel.onLoginActionFired) .disposed(by: disposeBag) // ViewModel var mailPlaceHolderText: Observable<String> { return .just(R.string.localizable.loginScene_MailPlaceHolder()) } _email .map(validationUsecase.email) .bind(to: _emailValidation) .disposed(by: disposeBag) _onLoginActionFired .withLatestFrom(Observable.combineLatest(_email, _password)) .subscribe(onNext: loginUsecase.login) .disposed(by: disposeBag)
  8. .7$ // ViewController mailTextField.placeholder = R.string.localizable .loginScene_MailPlaceHolder() usecase.mail .subscribe(onNext: {

    [unowned self] in self.set($0, to: mailTextField) }) .disposed(by: disposeBag) func textFieldDidEndEditing(_ textField: UITextField) { switch textField { case mailTextField: usecase.setMail(textField.text) // } } @objc private func onButtonTapped(sender: UIButton) { switch sender { case loginButton: usecase.login() // } }
  9. .7$ʹ໭͢͜ͱʹΑͬͯಘΒΕͨ΋ͷ w ൺֱతʹগͳ͍ίʔσΟϯάίετͱ࢓༷มߋʹର͢Δमਖ਼ίε τ w ѹ౗తʹগͳ͍3Y4XJGUͷ֤छ0QFSBUPSͳͲʹର͢Δशಘί ετ w ୯Ұํ޲˞σʔλϑϩʔʹΑΔσόοάͷ͠΍͢͞ w

    ແཧ໼ཧʹϦΞΫςΟϒϓϩάϥϛϯά˞ΛೖΕͳ͍͍ͯ͘ͱݴ ͏৺ཧతͷԺ΍͔͞ ˞ਖ਼֬ʹ͸$PDPB.7$ͷ৔߹͸7$͕.FEJBUPSύλʔϯΛར༻͍ͯ͠ΔͨΊݫີ ͳ୯Ұํ޲Ͱ͸ͳ͍͕ɺ.77.ͱൺ΂Ε͹͔ͳΓָͰ͋Δ ˞.77.Ͱ΋ผʹઈରશͯϦΞΫςΟϒͰ૊·ͳͯ͘͸ͳΒͳ͍ͱݴ͏ܾ·Γ͸ͳ͍ Ͱ͕͢ɺ΍͸Γ%BUB#JOEJOHͷ࣌఺Ͱͩ͜ΘΓ͕ͪͳ໘͕͋Δͱݸਓతʹࢥ͏
  10. ڭ܇ w ࢓༷͕׬શʹఆ·ͬͯͳ͍ஈ֊Ͱ͸ɺ੹຿Λࡉ͔͘෼ׂ͗͢͠Δͱٯʹ ࢓༷มߋʹର͢Δमਖ਼ίετ͕ߴ͍ w Ή͠Ζ͋Δఔ౓ʮ੹຿աଟʯͳઃܭͷํ͕࢓༷มߋʹॊೈ w ೲظͱͷઓ͍͕ڧ͍ΒΕͨ৔߹ɺແཧʹʮྑͦ͞͏ʯͳઃܭΛಋೖ͢ Δඞཁ͸ͳ͍ w

    ͲͷઃܭΛ࢖͏ΑΓ΋ɺઃܭͷΠϝʔδ͕ͲΕ͚ͩνʔϜϝϯόʔ ͱڞ༗Ͱ͖͍ͯΔ͔͕ॏཁ w .7$͸·ͩ·ͩݱ໾ʂ w গͳ͘ͱ΋ʮϦΞϧλΠϜߋ৽ʯ͸.7$Λ࠾༻͠ͳ͍ཧ༝ʹ͸ͳ Βͳ͍ w ઃܭʹۜͷ஄ؙ͸ͳ͍ʂ w ༷ʑͷઃܭͷϝϦοτɾσϝϦοτΛཧղ্ͨ͠Ͱͷݕ౼͕ඞཁ