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
4k
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
600
Unityテスト活動のふりかえり
adarapata
1
600
Gather.townはいいぞ その後
adarapata
1
1.6k
Unityでの開発事例
adarapata
3
23k
どこのご家庭にもあるシーンマネージャーの話
adarapata
2
8.4k
Gather.townはいいぞ
adarapata
2
2.4k
宴はいいぞ
adarapata
0
1.6k
わかった気になるモブプログラミング
adarapata
1
140
モブワークっぽいのをやっている話/Trying mobwork
adarapata
2
1.3k
Other Decks in Programming
See All in Programming
AI Agent Tool のためのバックエンドアーキテクチャを考える #encraft
izumin5210
5
1.4k
HTTPプロトコル正しく理解していますか? 〜かわいい猫と共に学ぼう。ฅ^•ω•^ฅ ニャ〜
hekuchan
2
550
PC-6001でPSG曲を鳴らすまでを全部NetBSD上の Makefile に押し込んでみた / osc2025hiroshima
tsutsui
0
200
Grafana:建立系統全知視角的捷徑
blueswen
0
250
AIの誤りが許されない業務システムにおいて“信頼されるAI” を目指す / building-trusted-ai-systems
yuya4
6
4k
tparseでgo testの出力を見やすくする
utgwkk
2
310
「コードは上から下へ読むのが一番」と思った時に、思い出してほしい話
panda728
PRO
39
26k
GISエンジニアから見たLINKSデータ
nokonoko1203
0
190
はじめてのカスタムエージェント【GitHub Copilot Agent Mode編】
satoshi256kbyte
0
120
フルサイクルエンジニアリングをAI Agentで全自動化したい 〜構想と現在地〜
kamina_zzz
0
320
新卒エンジニアのプルリクエスト with AI駆動
fukunaga2025
0
240
Developing static sites with Ruby
okuramasafumi
0
330
Featured
See All Featured
Odyssey Design
rkendrick25
PRO
0
440
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
51
Optimising Largest Contentful Paint
csswizardry
37
3.5k
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
2.2k
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
32
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
32
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
200
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
It's Worth the Effort
3n
187
29k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
55k
Stop Working from a Prison Cell
hatefulcrawdad
273
21k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
74
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