Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Zenjectを導入する前に
Search
いも
December 19, 2019
Programming
0
3.8k
Zenjectを導入する前に
2019/12/19 Roppongi.unity #6 のLT資料です
いも
December 19, 2019
Tweet
Share
More Decks by いも
See All by いも
UnityプログラミングバイブルR6号宣伝&Unity Logging小話
adarapata
0
380
Unityテスト活動のふりかえり
adarapata
1
500
Gather.townはいいぞ その後
adarapata
1
1.5k
Unityでの開発事例
adarapata
3
22k
どこのご家庭にもあるシーンマネージャーの話
adarapata
1
7.3k
Gather.townはいいぞ
adarapata
2
2.3k
宴はいいぞ
adarapata
0
1.3k
わかった気になるモブプログラミング
adarapata
1
84
モブワークっぽいのをやっている話/Trying mobwork
adarapata
2
1.2k
Other Decks in Programming
See All in Programming
現場で役立つモデリング 超入門
masuda220
PRO
15
3.1k
광고 소재 심사 과정에 AI를 도입하여 광고 서비스 생산성 향상시키기
kakao
PRO
0
160
3rd party scriptでもReactを使いたい! Preact + Reactのハイブリッド開発
righttouch
PRO
1
590
C#/.NETのこれまでのふりかえり
tomokusaba
1
180
カスタムしながら理解するGraphQL Connection
yanagii
1
1.5k
GCCのプラグインを作る / I Made a GCC Plugin
shouth
1
160
Importmapを使ったJavaScriptの 読み込みとブラウザアドオンの影響
swamp09
4
1.3k
LLM生成文章の精度評価自動化とプロンプトチューニングの効率化について
layerx
PRO
2
170
cXML という電子商取引の トランザクションを支える プロトコルと向きあっている話
phigasui
3
2.3k
弊社の「意識チョット低いアーキテクチャ」10選
texmeijin
5
24k
色々なIaCツールを実際に触って比較してみる
iriikeita
0
320
Better Code Design in PHP
afilina
PRO
0
110
Featured
See All Featured
How STYLIGHT went responsive
nonsquared
95
5.2k
What's in a price? How to price your products and services
michaelherold
243
12k
Become a Pro
speakerdeck
PRO
25
5k
10 Git Anti Patterns You Should be Aware of
lemiorhan
654
59k
Why You Should Never Use an ORM
jnunemaker
PRO
54
9k
Java REST API Framework Comparison - PWX 2021
mraible
PRO
28
8.2k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
126
18k
Gamification - CAS2011
davidbonilla
80
5k
Fashionably flexible responsive web design (full day workshop)
malarkey
404
65k
Build your cross-platform service in a week with App Engine
jlugia
229
18k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
92
16k
Speed Design
sergeychernyshev
24
600
Transcript
━━━━━━━━━━━━━━━━━ Zenjectを導⼊する前に いも(@adarapata) ━━━━━━━━━━━━━━━━━ 2019/12/19 Roppongi.unity #6 1
⾃⼰紹介 いも (@adarapata) adarapata.com 仕事でUnity触ってるエンジニア テスト、DIとかよく話すおじさん 2019/12/19 Roppongi.unity #6 2
宣伝 「ZenjectチョットワカルBook」 基礎的な使い⽅を纏めた本 多分⽇本で唯⼀のZenject本 boothで電⼦版販売中 後編もうちょっとまって 2019/12/19 Roppongi.unity #6 3
はなすこと DIフレームワークを導⼊するその前に考えること Zenject内部の話はあんまりしない 対象者 すでに動いているプロダクトにZenjectを導⼊しようとしている⼈ 2019/12/19 Roppongi.unity #6 4
Zenject is 便利 シングルトン無くせる! 疎結合な設計ができる! テスタビリティ⾼い! わが社もDIフレームワークでイケイケ開発だ! 2019/12/19 Roppongi.unity #6
5
既存プロダクトにZenjectを⼊れる 動いてるものにライブラリを⼊れるのドキドキするよね ミニマムにスタートしたくなるのが⼼情 特定のクラスだけDIするとかから始めたい 2019/12/19 Roppongi.unity #6 6
Zenject対応の⼀例 シングルトン依存 動的に作られるFoo public class Foo { public void DoFoo()
{ var some = BarSingleton.Instance.SomeLogic(); // some でなんやかんや } } テストを書きやすくしたい! シングルトン依存を無くしたい! 2019/12/19 Roppongi.unity #6 7
interfaceをBindしてDIだ! public class Foo { private IBarSingleton _bar; public Foo(IBarSingleton
bar) { _bar = bar; } public void DoFoo() { var some = _bar.SomeLogic(); // some でなんやかんや } } Container.Bind<Foo>().AsCached(); Container.Bind<IBarSingleton>().To<BarSingleton>().AsSingle(); 2019/12/19 Roppongi.unity #6 8
動的に作られるならFactoryにしないといけないよね public class Foo { private BarSingleton _bar; public Foo(BarSingleton
bar) { _bar = bar; } public void DoFoo() { var some = _bar.SomeLogic(); // some でなんやかんや } public class Factory : PlaceholderFactory<Foo> {} } Container.BindFactory<Foo, FooFactory>(); Container.Bind<IBarSingleton>().To<BarSingleton>().AsSingle(); 2019/12/19 Roppongi.unity #6 9
Fooを⽣成してたところもZenject対応必要だよね public class FooSpawner { private Foo.Facotry _factory; public FooSpawner(Foo.Factory
factory) { _factory = factory } public void Spawn() { // var foo = new Foo(); 今までこうだった var foo = _factory.Create(); } } Container.Bind<FooSpawner>().AsCached(); // 追加 Container.BindFactory<Foo, FooFactory>(); Container.Bind<BarSingleton>().AsSingle(); 2019/12/19 Roppongi.unity #6 10
FooSpawnerに依存しているクラスもZenject対応必要だよね ↑に依存してるやつも必要だよね ↑に依存してるやつ(ry ↑に依存し(ry ↑(ry 結局シーンのオブジェクト全部対応必要じゃね? 影響範囲やばい 1クラスを綺麗にしたかっただけなのに 2019/12/19 Roppongi.unity
#6 11
Zenject対応の⼀例 循環参照 public class Fizz { private Buzz _buzz; public
Fizz(Buzz buzz) { _buzz = buzz; } } public class Buzz { private Fizz _fizz; public Buzz(Fizz fizz) { _fizz = fizz; } } Zenjectはコンストラクタインジェクションの循環参照を許さない 2019/12/19 Roppongi.unity #6 12
フィールドインジェクションなどで頑張ることになる public class Fizz { [Inject] private Buzz _buzz; }
public class Buzz { [Inject] private Fizz _fizz; } 対応はできるがZenject以外の⽅法でこのクラスを扱うことは難しくなる 2019/12/19 Roppongi.unity #6 13
Zenjectを使おうとして明らかになることがある ⾃分のコードはどのような依存関係を持っているのか それは適切なものなのかが如実に表れる 循環参照があるとしんどくなる 1クラスに⼤量の依存があるとしんどくなる 階層がめっちゃ深くてもしんどくなる この部分だけZenjectみたいなつまみ⾷いは割と⼤変 これらを強引にZenjectの機能で解決しようとすると苦戦を強いられ導⼊コストと 運⽤コストが跳ね上がる 2019/12/19
Roppongi.unity #6 14
あなたのコードはDIできますか? DIフレームワークはコードを綺麗にしてくれない ⼈間がDIフレームワークを活⽤してコードを綺麗にする DIできる状態じゃないとDIできない禅問答 Zenjectを使う前に、そもそもZenjectを使えるような作り⽅にしないとい けない 2019/12/19 Roppongi.unity #6 15
Zenjectでしか解決できない問題はそんなにない スコープを狭めれば⼿動でDIはできる public class FooSpawner { public void Spawn() {
var foo = new Foo(BarSingleton.Instance); // Non Zenject //var foo = _factory.Create(); } } テストを書きやすくしたい! => シングルトン依存を無くしたい! => 2019/12/19 Roppongi.unity #6 16
インタフェースに依存させれば循環参照を無くせる public interface IFizz { } public class Fizz :
IFizz { private Buzz _buzz; public Fizz(Buzz buzz) { _buzz = buzz; } } public class Buzz { private IFizz _fizz; public Buzz(IFizz fizz) { _fizz = fizz; } } 2019/12/19 Roppongi.unity #6 17
Zenjectを使う = 設計と向き合うこと 導⼊しただけでは何も変わらない、導⼊できるかもわからない 疎結合になるのではなく、疎結合にしていかないといけなくなる リファクタリングはほぼ必須 リファクタリングの際にテストが活きてくる 2019/12/19 Roppongi.unity #6
18
Zenjectを導⼊する前に 銀の弾丸ではないことを理解する DIパターンを適⽤できるコードなのか⾒直す できない状態であるなら、今後どういうアプローチを取るのか考える 地道なリファクタリングしましょう Zenjectに依存しないこと 2019/12/19 Roppongi.unity #6 19
Zenjectに依存とは? コードレベルで⾒ると依存は避けられない(assembly的な意味で) ではなく、設計レベルで解決しなければならないものをZenjectを使って解決す ることを Zenjectに依存する と考えている 循環参照をフィールドインジェクションでねじ伏せる ProjectContextでグローバルなBindを⼤量展開 単⼀責任原則を⼤きく違反していてもInstallerで⼿軽に⼤量Bindできる ようにする
etc.. 鎮痛剤としては使えないことを理解する 2019/12/19 Roppongi.unity #6 20
それでもZenjectはいいぞ Zenjectを⼊れずとも運⽤するアプリなら設計とは向き合わなければならない そこでDIという選択肢が増えるのはよいこと 導⼊時のコストは未来への先⾏投資 OSSなので集合知がある。あなたの悩みは誰かが解決してる 誰かの悩みをあなたが解決できる 巨⼈の肩に乗っかろう 2019/12/19 Roppongi.unity #6
21