Pro Yearly is on sale from $80 to $50! »

我々のRealmはどこからやってくるのか

 我々のRealmはどこからやってくるのか

DIについての自由研究内容を発表しました。

Fb69c72d5af289d6674d2659246a5291?s=128

Tomohiro Nishimura

March 26, 2017
Tweet

Transcript

  1. զʑ ओޠ͕େ͖͍ ͷ 3FBMN͸Ͳ͔͜Β΍ͬ ͯ͘Δͷ͔ 3FBMN8PSME5PVS0TBLB JE4JYFJHIU

  2. ࣗݾ঺հ w JE4JYFJHIU !UPNPIJ@SP ੢ଜ༑༟ w גࣜձࣾ͸ͯͳΞϓϦέʔγϣϯΤϯδχΞ w ೥݄த్ೖࣾ w

    ฏ೔͸ຖ೔ʮ೔هʯΛॻ͍͍ͯ·͢ w IUUQTJYFJHIUIBUFOBCMPHDPN
  3. ͸ͯͳͰԿΛ΍͖͔ͬͯͨ αʔϏεએ఻ίʔφʔ w .BDLFSFM w IUUQTNBDLFSFMJP w ΧΫϤϜ "1*ɺΞϓϦ 

    w IUUQTLBLVZPNVKQ w ͸ͯͳϒϩά ΞϓϦ  w IUUQIBUFOBCMPHDPNHVJEFBQQ w ͸ͯͳϒοΫϚʔΫ ΞϓϦ  w IUUQCIBUFOBOFKQHVJEFBQQ
  4. ͓அΓ w 4XJGUͱ+BWB͕ೖΓཚΕ·͢ w J04"OESPJEܦݧऀͷํʹ఻ΘΓ͍ͨͱ͍͏ؾ࣋ͪ w ଞͷϓϥοτϑΥʔϜͷํ͝ΊΜͳ͍͞ w ͱ͍͍ͭͭ΋4XJGUଟΊͰ͢ w

    ίʔυΛͤ·͍εϥΠυʹ͓͞ΊΔʹ͸ɺදݱྗͷ๛ ͔ͳ4XJGU͕༗ར
  5. 3FBMN͸ Ͳ͔͜Β΍ͬͯ͘Δͷ͔

  6. 3FBMNΠϯελϯε͸ Ͳ͔͜Β΍ͬͯ͘Δͷ͔

  7. ૉ๿ͳํ๏ let realm = try! Realm() Realm realm = Realm.getDefaultInstance();

    4XJGU +BWB
  8. ΋͏ͪΐͬͱෳࡶͳྫ let configuration = Realm.Configuration(fileURL: url) let realm = try!

    Realm(configuration: configuration) RealmConfiguration configuration =
 new RealmConfiguration.Builder()
 .name("data")
 .build(); Realm realm = Realm.getInstance(configuration); 4XJGU +BWB
  9. Ұൠతͳ$POpHVSBUJPO RealmConfiguration config = new RealmConfiguration.Builder()
 .name("myrealm.realm")
 .encryptionKey(getKey())
 .schemaVersion(42)
 .modules(new

    MySchemaModule())
 .migration(new MyMigration())
 .build();
 
 Realm realm = Realm.getInstance(config); +BWB
  10. ઃఆͷΠϯελϯε͸Ͳ͜ʹ ࣋ͭͷ͕ྑ͍ͷͩΖ͏͔

  11. ྫ͑͹4JOHMFUPO class Locator { private static let instance = Locator()

    public var realmConfiguration: Realm.Configuration { var configuration = Realm.Configuration() configuration.fileURL = configuration.fileURL! .deletingLastPathComponent() .appendingPathComponent("main.realm") return configuration } } 4XJGU
  12. ઃఆΛ࡞Βͳͯ͘Α͘ͳͬͨ let configuration = Locator.instance.realmConfiguration let realm = try! Realm(configuration:

    configuration) RealmConfiguration configuration = Locator.getInstance().getRealmConfig(); Realm realm = Realm.getInstance(configuration); 4XJGU +BWB
  13. 3FBMN΋ఏڙͯ͠͠·͏ class Locator { static let instance = Locator() public

    var realmConfiguration: Realm.Configuration { return // Realm.ConfigurationΛ࡞Δ } public var realm: Realm { return try! Realm(configuration: realmConfiguration) } } 4XJGU
  14. ͔ͳΓ୯७ԽͰ͖ͨ let realm = Locator.instance.realm 4XJGU +BWB Realm realm =

    Locator.getInstance().getRealm();
  15. None
  16. <࠶ܝ>-PDBUPS class Locator { static let instance = Locator() public

    var realmConfiguration: Realm.Configuration { return // Realm.ConfigurationΛ࡞Δ } public var realm: Realm { return try! Realm(configuration: realmConfiguration) } } 4XJGU
  17. ߽՚ͳ-PDBUPS public class Locator { // ɾɾɾུɾɾɾ public RealmConfiguration getRealmConfiguration()

    { … } public Realm getRealm() { … } public APIClient getApiClient() { … } public Tracker getTracker() { … } public UserRepository getUserRepository() { … } public FriendRepository getFriendRepository() { … } public ItemRepository getItemRepository() { … } } +BWB
  18. ͳΜͰ΋͘ΕΔ܅

  19. 4FSWJDF -PDBUPS 1BUUFSO

  20. 4FSWJDF-PDBUPS w ͋ΔίϯϙʔωϯτΛ࢖͏ͷʹผͷෳ਺ͷί ϯϙʔωϯτ͕ඞཁͳ৔߹ " # $

  21. 4FSWJDF-PDBUPS w ͋Δίϯϙʔωϯτ͸ඞཁͳίϯϙʔωϯτ Λ୳ͯ͘͠ΕΔԿ͔͚ͩ஌͍ͬͯΕ͹Α͍ͱ ͍͏͜ͱʹ͢Δ " # $ 4-

  22. ඞཁͳίϯϙʔωϯτΛ ୳ͯ͠ ࡞ͬͯ ͘ΕΔ Կ͔Λ༻ҙ͢Δ

  23. 4FSWJDF -PDBUPS 1BUUFSO

  24. ͱ͜ΖͰςετ͍ͨ͠ w ͨͱ͑͹"1*͔Β+40/Λऔಘͯ͠ɺ3FBMN ʹਖ਼͘͠อଘ͞ΕΔ͔Λ֬ೝ͍ͨ͠

  25. 3FQPTJUPSZͷྫ class UserRepository { private let realm = Locator.instance.realm private

    let apiClient = Locator.instance.apiClient func load(byID id: String, callback: (User) -> Void) { // APIݺͼग़͠ } private func save(json: [AnyHashable: Any]) { // Realmʹอଘ } } 4XJGU
  26. ࠔΓͦ͏ w ςετͰ͚ͩJONFNPSZͷ3FBMNΛ࢖ ͍ͨ͘ͳͬͨΒʁ w "1*ݺͼग़͠Λελϒͨ͘͠ͳͬͨΒʁ

  27. <࠶ܝ>3FQPTJUPSZͷྫ class UserRepository { private let realm = Locator.instance.realm private

    let apiClient = Locator.instance.apiClient func load(byID id: String, callback: (User) -> Void) { // APIݺͼग़͠ } private func save(json: [AnyHashable: Any]) { // Realmʹอଘ } } 4XJGU
  28. -PDBUPSΛίϯετϥΫλʹ ౉ͤΔΑ͏ʹ͢Δ public class UserRepository {
 private final Realm realm;


    private final APIClient apiClient;
 
 public UserRepository(Locator locator) {
 realm = locator.getRealm();
 apiClient = locator.getApiClient();
 }
 } +BWB
  29. -PDBUPSΛࠩ͠ସ͑ΒΕΔΑ ͏ʹΠϯλʔϑΣʔεʹ͢Δ interface ILocator {
 RealmConfiguration getRealmConfiguration();
 Realm getRealm();
 APIClient

    getApiClient();
 Tracker getTracker();
 
 UserRepository getUserRepository();
 FriendRepository getFriendRepository();
 ItemRepository getItemRepository();
 } +BWB
  30. *-PDBUPSΛίϯετϥΫλʹ ౉ͤΔΑ͏ʹ͢Δ public class UserRepository {
 private final Realm realm;


    private final APIClient apiClient;
 
 public UserRepository(ILocator locator) {
 realm = locator.getRealm();
 apiClient = locator.getApiClient();
 }
 } +BWB
  31. .PDL-PDBUPSΛ࡞Δ public class MockLocator implements ILocator {
 @Override
 public RealmConfiguration

    getRealmConfiguration() { return // in-memory Configuration }
 
 @Override
 public Realm getRealm() { return Realm.getInstance(realmConfiguration()); }
 
 @Override
 public APIClient getApiClient() { return // MockApiClient }
 
 @Override public Tracker getTracker() { … }
 @Override public UserRepository getUserRepository() { … }
 @Override public FriendRepository getFriendRepository() { … }
 @Override public ItemRepository getItemRepository() { … }
 } +BWB
  32. ςετͷ༷ࢠ let locator = MockLocator() let repository = UserRepository(locator) 4XJGU

    +BWB Locator locator = new MockLocator();
 UserRepository repository =
 new UserRepository(locator);
  33. ΍ͬͨ͜ͱ w 3FQPTJUPSZ͕ίϯετϥΫλͰ4FSWJDF -PDBUPSΛड͚औΕΔΑ͏ʹͨ͠ w 4FSWJDF-PDBUPSͷΠϯλʔϑΣʔεΛ༻ ҙͯࠩ͠͠ସ͑ΒΕΔΑ͏ʹͨ͠

  34. ͜͏ͩͬͨͷ͕ class UserRepository { private let realm: Realm private let

    apiClient: APIClient init() { realm = Locator.instance.realm apiClient = Locator.instance.apiClient } } 4XJGU
  35. ͜͏ͳΓ·ͨ͠ class UserRepository { private let realm: Realm private let

    apiClient: APIClient init(locator: LocatorProtocol) { realm = locator.realm apiClient = locator.apiClient } } 4XJGU
  36. None
  37. <࠶ܝ>.PDL-PDBUPSΛ࡞Δ public class MockLocator implements ILocator {
 @Override
 public RealmConfiguration

    getRealmConfiguration() { return // in-memory Configuration }
 
 @Override
 public Realm getRealm() { return Realm.getInstance(realmConfiguration()); }
 
 @Override
 public APIClient getApiClient() { return // MockApiClient }
 
 @Override public Tracker getTracker() { … }
 @Override public UserRepository getUserRepository() { … }
 @Override public FriendRepository getFriendRepository() { … }
 @Override public ItemRepository getItemRepository() { … }
 } +BWB
  38. ྫྷ੩ʹߟ͑Δͱʜ w ςετ༻ͷ3FBMNͱ"1*$MJFOU͕ཉ͍ͩ͠ ͚ͩͬͨ w 4FSWJDF-PDBUPSͷΠϯλʔϑΣʔεʹै ͏ͨΊʹͳΜͰ͜ΜͳʹେྔʹίʔυΛॻ͔ ͳ͍ͱ͍͚ͳ͍ͷ͔

  39. զʑ͕ཉ͔ͬͨ͠΋ͷ protocol UserRepositoryDependency { var realmConfiguration: Realm.Configuration { get }

    var realm: Realm { get } var apiClient: APIClient { get } } 4XJGU
  40. ͦ΋ͦ΋3FQPTJUPSZ͕͜ͷ ΠϯλʔϑΣʔεΛड͚औΕ ͹ྑ͔ͬͨͷͰ͸ͳ͍͔

  41. ͜͏͍͏ײ͡ class UserRepository { private let realm: Realm private let

    apiClient: APIClient init(dependency: UserRepositoryDependency) { realm = dependency.realm apiClient = dependency.apiClient } } 4XJGU
  42. Α͘ͳͬͨ.PDL-PDBUPS class MockLocator: UserRepositoryDependency { var realmConfiguration: Realm.Configuration { return

    .Configuration(inMemoryIdentifier: "test") } var realm: Realm { return try! Realm(configuration: realmConfiguration) } var apiClient: APIClientProtocol { return new MockApiClient(); } } 4XJGU
  43. 4FSWJDF-PDBUPS͸͜ͷΠϯ λʔϑΣʔεl΋z࣮૷͢Δ class Locator: LocatorProtocol, UserRepositoryDependency { var realmConfiguration: Realm.Configuration

    { … } var realm: Realm { … } var apiClient: APIClient { … } var tracker: Tracker { … } var userRepository: UserRepository { … } var friendRepository: FriendRepository { … } var itemRepository: ItemRepository { … } } 4XJGU
  44. ࠷ॳͷґଘؔ܎ 6TFS3FQPTJUPSZ -PDBUPS

  45. ΠϯλʔϑΣʔεΛಋೖͨ͋͠ ͱͷґଘؔ܎ 6TFS3FQPTJUPSZ *-PDBUPS -PDBUPS

  46. ৽͍͠ґଘؔ܎ 6TFS3FQPTJUPSZ -PDBUPS 6TFS3FTQPTJUPSZ% FQFOEFODZ

  47. ґଘؔ܎͕ٯసͨ͠

  48. %FQFOEFODZ *OWFSTJPO 1SJODJQMF

  49. ґଘੑٯసͷݪଇ %*1

  50. ґଘੑٯసͷݪଇ %*1 w ্ҐͷϞδϡʔϧ͸ԼҐͷϞδϡʔϧʹґଘ ͯ͠͸ͳΒͳ͍ɻͲͪΒͷϞδϡʔϧ΋ʮந ৅ʯʹґଘ͢΂͖Ͱ͋Δɻ w ʮந৅ʯ͸࣮૷ͷৄࡉʹґଘͯ͠͸ͳΒͳ͍ɻ ࣮૷ͷৄࡉ͕ʮந৅ʯʹґଘ͢΂͖Ͱ͋Δɻ

  51. ࠷ॳͷґଘؔ܎ 6TFS3FQPTJUPSZ -PDBUPS

  52. %*1 Ұ෦ Λద༻ͨ͠ґଘؔ܎ 6TFS3FQPTJUPSZ *-PDBUPS -PDBUPS

  53. %*1Λద༻ͨ͋͠ͱͷґଘؔ܎ 6TFS3FQPTJUPSZ -PDBUPS 6TFS3FTQPTJUPSZ% FQFOEFODZ

  54. ґଘੑٯసͷݪଇ %*1

  55. ͱ͜ΖͰίϯετϥΫλΛ࢖ ͑ͳ͍৔߹͸Ͳ͏͢Ε͹

  56. ΞϓϦ։ൃͰίϯετϥΫλ͕ ࢖͍ʹ͍͘ͱ͜Ζ w J04 w 7JFX$POUSPMMFS w "OESPJE w "DUJWJUZ

    w 'SBHNFOU
  57. ߟ͑ΒΕΔํ๏ w ϓϩύςΟʹ୅ೖ͢Δ w ηολʔΛ༻ҙ͢Δ w ॳظԽϝιουΛ༻ҙ͢Δ

  58. 7JFX$POUSPMMFSͩͱ͜͏͍ ͏͜ͱΛ͠·͢ΑͶ override func prepare(for segue: …) { if let

    vc = segue.destination as? NextViewController { vc.locator = Locator.instance } } 4XJGU
  59. ܽ఺ w มߋ͢΂͖Ͱͳ͍ϓϩύςΟΛ͖ͪΜͱӅṭ Ͱ͖ͳ͍ w ঢ়ଶ͕มΘΔ͔΋͠Εͳ͍ΦϒδΣΫτͱͷ ΍ΓͱΓ͸ۤ௧͕൐͏

  60. ΋͏Ұ౓࠷ॳͷ໰͍ʹ໭Δ

  61. 3FBMNΠϯελϯε͸ Ͳ͔͜Β΍ͬͯ͘Δͷ͔

  62. 3FBMNΠϯελϯε͸ 4FSWJDF-PDBUPS ͔Β΍ͬͯ͘Δ

  63. 7JFX$POUSPMMFS͸ 4FSWJDF-PDBUPSʹ ґଘ͍ͯ͠Δ

  64. ͜ͷґଘΛͲ͏΍ͬͯղܾ͢ Ε͹͍͍ͷ͔

  65. %FQFOEFODZ *OKFDUJPO 1BUUFSO

  66. https://www.martinfowler.com/articles/injection.html

  67. http://kakutani.com/trans/fowler/injection.html

  68. ґଘΦϒδΣΫτ஫ೖ ґଘੑ஫ೖ

  69. 7JFX$POUSPMMFS͸ 4FSWJDF-PDBUPSʹ ґଘ͍ͯ͠Δ

  70. "͸#ʹґଘ͍ͯ͠Δ

  71. #͸"ͷ ґଘ ΦϒδΣΫτ Ͱ͋Δ

  72. ґଘΦϒδΣΫτ  %FQFOEFODZ

  73. %FQFOEFODZ ґଘΦϒδΣΫτ  *OKFDUJPO ஫ೖ

  74. ஫ೖʁ

  75. ґଘΦϒδΣΫτΛ ඞཁͱ͍ͯ͠Δ ίϯϙʔωϯτʹ౉͢

  76. Ώ͔͍ͳ஥ؒͨͪ w $POTUSVDUPS*OKFDUJPO w 1SPQFSUZ 4FUUFS *OKFDUJPO w *OUFSGBDF*OKFDUJPO w

    .FUIPE*OKFDUJPO w BOENPSFʜ
  77. ͳΜ͔΍΍ͦ͜͠͏

  78. ͖ͬ͞΍Γ·ͨ͠ΑͶ

  79. $POTUSVDUPS*OKFDUJPO let locator = Locator.instance let repository = UserRepository(locator: locator)

    4XJGU +BWB Locator locator = Locator.getInstance();
 Repository repository = new UserRepository(locator);
  80. 1SPQFSUZ*OKFDUJPO override func prepare(for segue: …) { if let vc

    = segue.destination as? NextViewController { vc.locator = Locator.instance } } 4XJGU
  81. ʮґଘΦϒδΣΫτΛ ඞཁͱ͍ͯ͠Δ ίϯϙʔωϯτʹ౉͢ʯ ͜ͱʹ໊લΛ෇͚͚ͨͩ

  82. l%FQFOEFODZ*OKFDUJPOJTB EPMMBSUFSNGPSBDFOUDPODFQUz http://www.jamesshore.com/Blog/Dependency- Injection-Demystified.html - James Shore

  83. %FQFOEFODZ ґଘΦϒδΣΫτ  *OKFDUJPO ஫ೖ

  84. 1SPQFSUZ*OKFDUJPOΛ ফ͍ͨ͠ w ܽ఺ w มߋ͢΂͖Ͱͳ͍ϓϩύςΟΛ͖ͪΜͱӅ ṭͰ͖ͳ͍ w ঢ়ଶ͕มΘΔ͔΋͠Εͳ͍ΦϒδΣΫτͱ ͷ΍ΓͱΓ͸ۤ௧͕൐͏

  85. ࠓճͷ࡞ઓ w 1SPUPDPM&YUFOTJPO J04  w %*'SBNFXPSL w %BHHFS̉ "OESPJE

     w J04΋σϑΝΫτελϯμʔυ΄͍͠
  86. 1SPUPDPM&YUFOTJPO J04 w *OUFSGBDFͷσϑΥϧτ࣮૷Λ࢖ͬͯɺͦΕ Λ࣮૷͢ΔίϯϙʔωϯτʹґଘΦϒδΣΫ τΛ஫ೖ͢Δ w σϑΥϧτϝιου͸+BWB͔ΒͳͷͰ "OESPJEͰ͸Ͱ͖ͳ͍

  87. 1SPUPDPM&YUFOTJPO protocol WithLocator { var locator: LocatorProtocol { get }

    } extension WithLocator { var locator: LocatorProtocol { return Locator.instance } } 4XJGU
  88. 1SPUPDPM&YUFOTJPO class RootViewController: UIViewController, WithLocator { override func viewDidAppear(_ animated:

    Bool) { super.viewDidAppear(animated) // ຊ౰͸ userRepository ࢖͑͹ྑͦ͞͏Ͱ͢Ͷ locator.apiClient.fetchUser(byID: “xxxx”) { [weak self] result in try! locator.realm.write { self?.locator.realm.add(User(json: result.json)) } } } } 4XJGU
  89. ิ଍ w 4FSWJDF-PDBUPS͡Όͳͯ͘ґଘΦϒδΣ ΫτΛ௚઀஫ೖͯ͠΋Α͍ w ґଘΛऔಘ͢ΔϓϩύςΟ͕ಥવੜ͑ΔͷͰ ίʔυ͕௥͍ʹ͘͘ͳΔ

  90. https://speakerdeck.com/yashigani/dependency- injection-in-ios-apps

  91. %BHHFS̉ "OESPJE w (PPHMF੍ͷ%*'SBNFXPSL w $PNQPOFOU͕ґଘπϦʔͷ؅ཧ w .PEVMF͕ґଘͷڙڅ 4FSWJDF-PDBUPS 

    w ͱ͖ͬͭʹ͍͕֮͑͘Δͱґଘ؅ཧ͕ͱͯ΋ ָʹͳΔ
  92. "DUJWJUZʹ*OKFDU͢Δ༷ࢠ public class MainActivity extends AppCompatActivity {
 @Inject
 Locator mLocator;


    
 @Override
 public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 
 ((App) getApplicationContext())
 .getApplicationComponent()
 .newActivityComponentBuilder()
 .activity(this)
 .build()
 .inject(this);
 }
 } +BWB
  93. ґଘ͕ଟ͍ͱ public class MainActivity extends AppCompatActivity {
 @Inject
 Locator mLocator;


    
 @Inject
 Realm mRealm;
 
 @Inject
 ApiClient mApiClient;
 
 @Inject
 UserRepository mUserRepository;
 
 @Inject
 FriendRepository mFriendRepository;
 } +BWB
  94. ิ଍ w ґଘΛϑϨʔϜϫʔΫʹ؅ཧͯ͠΋Β͑Δͱ ָ w 1SPWJEF3FBMNΛJOKFDUͯ͠ผεϨου Ͱ࢖͏ͳͲ΋؆୯ w %*΁ͷཧղ͕ඞཁͰɺϑϨʔϜϫʔΫࣗମ΋ ෳࡶͳͷͰɺಋೖ࣌ͷϋʔυϧ͸ߴ͍

  95. ;Γ͔͑Γ

  96. ;Γ͔͑Γ w 4FSWJDF-PDBUPSΛ࢖ͬͯؾʹ͢Δ΂͖૬ खΛݶఆ͢Δज़ʹ͍ͭͯ࿩͠·ͨ͠ w *P$%*1ʹ͍ͭͯগ͠৮Ε·ͨ͠ w %*ʹ͍ͭͯ࿩͠·ͨ͠ w ࣮ࡍͷ%*ͷద༻ྫʹ͍ͭͯ࿩͠·ͨ͠

  97. 3FBMN͸ Ͳ͔͜Β΍ͬͯ͘Δͷ͔

  98. 3FBMN͸ %*ʹΑͬͯ  ֎͔Β΍͖ͬͯ·͢

  99. ͝੩ௌ͋Γ͕ͱ͏ ͍͟͝·ͨ͠