Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Zenjectを導入する前に
Search
いも
December 19, 2019
Programming
4.1k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Zenjectを導入する前に
2019/12/19 Roppongi.unity #6 のLT資料です
いも
December 19, 2019
More Decks by いも
See All by いも
UnityプログラミングバイブルR6号宣伝&Unity Logging小話
adarapata
0
660
Unityテスト活動のふりかえり
adarapata
1
710
Gather.townはいいぞ その後
adarapata
1
1.7k
Unityでの開発事例
adarapata
3
23k
どこのご家庭にもあるシーンマネージャーの話
adarapata
2
8.9k
Gather.townはいいぞ
adarapata
2
2.5k
宴はいいぞ
adarapata
0
2.3k
わかった気になるモブプログラミング
adarapata
1
190
モブワークっぽいのをやっている話/Trying mobwork
adarapata
2
1.3k
Other Decks in Programming
See All in Programming
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
310
golang-bob.pdf
iwatsukayura
0
130
[2026-10-09]一枚の布で作らなくてもいい。 信頼性は「パッチワーク」で紡がれる~既存の運用と新しい可能性をつなぎ合わせてきたCREの話~
tosite
0
110
ChromeでローカルLLM
ryu1013
0
160
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
1
860
sbt 2.0: takeoff
eed3si9n
0
170
npm との違いを手がかりにGo の依存管理を理解したい
optim
0
1k
ハーネス設計入門 〜 基礎知識の整理から実務へのステップアップ 〜
kinopeee
28
34k
RAG の “R” を Swift で覗いてみる 〜「意味から探す」検索の仕組み〜
nao_randd
0
170
[2026-09-26]空論ジェネリックプロセス~テスト資産とAIで紡ぐ、再現可能なパフォーマンスチューニングの話~
tosite
0
270
Event is what happens
moro
2
1.2k
當我們開始不讀 Code - AI Agent 時代,Code Review 與 Clean Code 還剩下什麼?
jame2408
1
290
Featured
See All Featured
Between Models and Reality
mayunak
4
500
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.8k
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
2
330
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.4k
YesSQL, Process and Tooling at Scale
rocio
174
15k
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.6k
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
3.2k
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
1.1k
Paper Plane
katiecoart
PRO
5
54k
Building Flexible Design Systems
yeseniaperezcruz
330
41k
AI: The stuff that nobody shows you
jnunemaker
PRO
10
1.2k
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