Successfully reported this slideshow.

ワタシはSingletonがキライだ

33

Share

Loading in …3
×
1 of 38
1 of 38

ワタシはSingletonがキライだ

33

Share

Description

第50回Cocoa勉強会関西の発表資料です。

Transcript

  1. 1. ワタシは Singletonがキライだ かねうちてつや / @kaniza 2013.6.1 第50回 Cocoa勉強会関西
  2. 2. 自己紹介 かねうちてつや @kaniza id:kaniza Cocoa勉強会関西2代目代表(2012年まで) 元Java屋さん(5年くらい前)
  3. 3. Singleton おさらい GoF デザインパターンの1つ オブジェクトの単一性を保証する 頻繁に利用される [HogeManager sharedInstance] とか
  4. 4. よくある光景 エンジニア仲間とビールを飲む さらに飲む Singleton を dis りはじめる まわりが困る
  5. 5. なぜ困るのか 問題意識が共有できない 解決策が見えない ろれつが回っていない
  6. 6. 今日のゴール ろれつが回らなくなる前に 問題意識を共有して解決策を提案する
  7. 7. 前提となる価値観 単体テストしたい でもできてない グローバル変数は悪 ≒ 密結合は悪
  8. 8. よい設計 疎結合 高凝集 適切な名前 変更時の影響範囲が予測可能かつ最小限
  9. 9. Big Ball of Mud 最も人気のあるソフトウェアアーキテクチ ャは Big Ball of Mud(大きな泥だんご)である
  10. 10. 設計のイメージ MainViewController SongStore SongManager DetailViewController ArtworkGenerator 結合度: 低
  11. 11. 現実の実装 MainViewController SongStore SongManager DetailViewController ArtworkGenerator 結合度: 高 Big Ball of Mud
  12. 12. Singletonの誘惑 設計上、離れた場所にある”コンポーネン ト”への参照が欲しくなったとき Managed Object Context とか HogeManager とか クラスメソッドならどこからでも見える
  13. 13. 典型的な実装 + (id)sharedInstance { static HogeManager *instance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [[self alloc] init]; }); return instance; } このクラスメソッドでのみアクセスさせる
  14. 14. これってグローバル変数
  15. 15. 単体テスト クラスごと、メソッドごとにテストコード を書いて自動化する それにはオブジェクトが「単体」で動く必 要がある ファイルシステムやネットワークは邪魔
  16. 16. static 結合はテストの敵 MyClass FileManager ConnectionManager static static テストコードからはファイルや ネットワークアクセスを防げない Test Code
  17. 17. dynamic 結合なら何とかなる MyClass MockFileManager MockConnManager dynamic dynamic テストコードからモック オブジェクトに差し替え可能 Test Code
  18. 18. Singleton と static 結合 Singleton は static な結合を招く インスタンスの数は問題ではない アクセス方法を static に規定するのが悪 static 結合はテスト不能なクラスへの道
  19. 19. Singleton は単体テストの敵
  20. 20. キライになってきた?
  21. 21. 解決策
  22. 22. DI: Dependency Injection 依存性注入 オブジェクトが依存先を解決しない 必要なものは与えられる。取りに行くな 取りに行くときにSingletonの誘惑が....
  23. 23. DI コンテナ 専用のコンテナオブジェクトにコンポーネ ントの情報を登録 コンポーネントの依存関係を解決して生成 コンポーネントインスタンスの数も管理 (普通は1個でいいはず) 原則、コンポーネントの alloc init は不要に
  24. 24. DIコンテナの依存性解決 A B C Cが必要になったらA, B, Cの順に生成してくれる 依存 依存 依存
  25. 25. オブジェクト生成は大仕事 あるオブジェクトを生成するのに必要なオ ブジェクトを えるのはけっこう大変 他のオブジェクトを生成するためだけに依 存関係が発生してしまうことも 大変なのでコンテナに任せてしまおう
  26. 26. Cocoa 向け DI コンテナ
  27. 27. Typhoon Framework
  28. 28. Typhoon Framework 元 Java 屋に親しみやすいデザイン コンポーネント情報を Block で書ける コンポーネント側をほぼいじらないっぽい TyphoonAssembly のサブクラスにコンポーネン ト情報を記述、TyphoonFactoryから取得
  29. 29. Cocoa Singleton あるある NSManagedObjectContext AppDelegate から取得? NSBundle mainBundle
  30. 30. CoreDataBooks on Typhoon
  31. 31. CoreDataBooks on Typhoon Apple のサンプルコードを Typhoon ベースに変 換 AppDelegate の Core Data Stack コードを一掃 コンポーネントは他のコンポーネントへの 参照を注入される サブクラス化して細かいパラメータ初期化
  32. 32. DIの気持ち悪さ 別名 IoC (Inversion of Control: 制御の反転) 取りに行くのではなく与えられる 自分でやってた部分を他人に任せる 中身がよく見えなくなる
  33. 33. IoC はオブジェクト指向の基本 フロー型からイベントドリブンへの流れは まさに「制御の反転」 viewDidLoad とか applicationDidFinishLaunching:とか だんだん気持ち良くなる
  34. 34. DI コンテナの誤解 コンポーネントを取得するためにコンテナ へのアクセスが多発する コンテナへのアクセスはごく一部。基本 的に注入されたコンポーネントを使う 生成が必要ならファクトリオブジェクト をコンポーネントとして注入する
  35. 35. DI コンテナの誤解 テストコードでもコンテナを使う ふつう使わない。テストコードから直接 モックオブジェクトなどを注入する initializer が長くなる 本当かも。でも自分で呼ばないし!
  36. 36. まとめ Singleton は現代のグローバル変数。結合度が 高くテストしにくいコードを招く SingletonでやりたいことはTyphoon などの DIコ ンテナを使えば美しく実現できる 疎結合でテストしやすいコードバンザイ

Description

第50回Cocoa勉強会関西の発表資料です。

Transcript

  1. 1. ワタシは Singletonがキライだ かねうちてつや / @kaniza 2013.6.1 第50回 Cocoa勉強会関西
  2. 2. 自己紹介 かねうちてつや @kaniza id:kaniza Cocoa勉強会関西2代目代表(2012年まで) 元Java屋さん(5年くらい前)
  3. 3. Singleton おさらい GoF デザインパターンの1つ オブジェクトの単一性を保証する 頻繁に利用される [HogeManager sharedInstance] とか
  4. 4. よくある光景 エンジニア仲間とビールを飲む さらに飲む Singleton を dis りはじめる まわりが困る
  5. 5. なぜ困るのか 問題意識が共有できない 解決策が見えない ろれつが回っていない
  6. 6. 今日のゴール ろれつが回らなくなる前に 問題意識を共有して解決策を提案する
  7. 7. 前提となる価値観 単体テストしたい でもできてない グローバル変数は悪 ≒ 密結合は悪
  8. 8. よい設計 疎結合 高凝集 適切な名前 変更時の影響範囲が予測可能かつ最小限
  9. 9. Big Ball of Mud 最も人気のあるソフトウェアアーキテクチ ャは Big Ball of Mud(大きな泥だんご)である
  10. 10. 設計のイメージ MainViewController SongStore SongManager DetailViewController ArtworkGenerator 結合度: 低
  11. 11. 現実の実装 MainViewController SongStore SongManager DetailViewController ArtworkGenerator 結合度: 高 Big Ball of Mud
  12. 12. Singletonの誘惑 設計上、離れた場所にある”コンポーネン ト”への参照が欲しくなったとき Managed Object Context とか HogeManager とか クラスメソッドならどこからでも見える
  13. 13. 典型的な実装 + (id)sharedInstance { static HogeManager *instance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [[self alloc] init]; }); return instance; } このクラスメソッドでのみアクセスさせる
  14. 14. これってグローバル変数
  15. 15. 単体テスト クラスごと、メソッドごとにテストコード を書いて自動化する それにはオブジェクトが「単体」で動く必 要がある ファイルシステムやネットワークは邪魔
  16. 16. static 結合はテストの敵 MyClass FileManager ConnectionManager static static テストコードからはファイルや ネットワークアクセスを防げない Test Code
  17. 17. dynamic 結合なら何とかなる MyClass MockFileManager MockConnManager dynamic dynamic テストコードからモック オブジェクトに差し替え可能 Test Code
  18. 18. Singleton と static 結合 Singleton は static な結合を招く インスタンスの数は問題ではない アクセス方法を static に規定するのが悪 static 結合はテスト不能なクラスへの道
  19. 19. Singleton は単体テストの敵
  20. 20. キライになってきた?
  21. 21. 解決策
  22. 22. DI: Dependency Injection 依存性注入 オブジェクトが依存先を解決しない 必要なものは与えられる。取りに行くな 取りに行くときにSingletonの誘惑が....
  23. 23. DI コンテナ 専用のコンテナオブジェクトにコンポーネ ントの情報を登録 コンポーネントの依存関係を解決して生成 コンポーネントインスタンスの数も管理 (普通は1個でいいはず) 原則、コンポーネントの alloc init は不要に
  24. 24. DIコンテナの依存性解決 A B C Cが必要になったらA, B, Cの順に生成してくれる 依存 依存 依存
  25. 25. オブジェクト生成は大仕事 あるオブジェクトを生成するのに必要なオ ブジェクトを えるのはけっこう大変 他のオブジェクトを生成するためだけに依 存関係が発生してしまうことも 大変なのでコンテナに任せてしまおう
  26. 26. Cocoa 向け DI コンテナ
  27. 27. Typhoon Framework
  28. 28. Typhoon Framework 元 Java 屋に親しみやすいデザイン コンポーネント情報を Block で書ける コンポーネント側をほぼいじらないっぽい TyphoonAssembly のサブクラスにコンポーネン ト情報を記述、TyphoonFactoryから取得
  29. 29. Cocoa Singleton あるある NSManagedObjectContext AppDelegate から取得? NSBundle mainBundle
  30. 30. CoreDataBooks on Typhoon
  31. 31. CoreDataBooks on Typhoon Apple のサンプルコードを Typhoon ベースに変 換 AppDelegate の Core Data Stack コードを一掃 コンポーネントは他のコンポーネントへの 参照を注入される サブクラス化して細かいパラメータ初期化
  32. 32. DIの気持ち悪さ 別名 IoC (Inversion of Control: 制御の反転) 取りに行くのではなく与えられる 自分でやってた部分を他人に任せる 中身がよく見えなくなる
  33. 33. IoC はオブジェクト指向の基本 フロー型からイベントドリブンへの流れは まさに「制御の反転」 viewDidLoad とか applicationDidFinishLaunching:とか だんだん気持ち良くなる
  34. 34. DI コンテナの誤解 コンポーネントを取得するためにコンテナ へのアクセスが多発する コンテナへのアクセスはごく一部。基本 的に注入されたコンポーネントを使う 生成が必要ならファクトリオブジェクト をコンポーネントとして注入する
  35. 35. DI コンテナの誤解 テストコードでもコンテナを使う ふつう使わない。テストコードから直接 モックオブジェクトなどを注入する initializer が長くなる 本当かも。でも自分で呼ばないし!
  36. 36. まとめ Singleton は現代のグローバル変数。結合度が 高くテストしにくいコードを招く SingletonでやりたいことはTyphoon などの DIコ ンテナを使えば美しく実現できる 疎結合でテストしやすいコードバンザイ

More Related Content

×