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
Humble Object Patternな話
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
いも
February 21, 2019
Programming
2.3k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Humble Object Patternな話
Roppongi.unity #01の資料です
いも
February 21, 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
Web Framework Benchmark Battle 2026, Any%
a_matsuda
3
3k
HTML-in-Canvasで作る未来のWeb UI表現
clockmaker
5
5.8k
学びを記事・スライド・Xへ高速展開する― AI-assisted Learning Loopで回すコンテンツ生成術
ochtum
0
150
見えないものを探る要求要件定義に必要な基本的思考 / invisible-requirement-thinking
minodriven
15
8.8k
sbt 2.0: takeoff
eed3si9n
0
170
golang-bob.pdf
iwatsukayura
0
140
気持ちぃ〜角丸 Squircle
ryu1013
0
340
AWS CDKのカスタムリソースでContinuum(旧Security Agent)を実装した話 | Implementing Continuum (formerly Security Agent) via AWS CDK Custom Resource
akihisaikeda
2
170
Agentic Software Factoryに、すごく賢いIF文を。 / super smart IF statement into the Agentic Software Factory.
rkaga
8
2.4k
Python Lambdaにおけるテストしやすい設計とAI支援の活用 / Designing Testable Python Lambda Functions with AI
kitano_yuichi
1
200
Unity6 URPによる海底をテーマにしたVJシステムの解説 | Unity Shader 完全に理解した 勉強会
gam0022
0
380
Vue Fes Japan の “作る側”に関わってみて
naokihaba
1
190
Featured
See All Featured
Joys of Absence: A Defence of Solitary Play
codingconduct
1
550
Building Applications with DynamoDB
mza
96
7.3k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
31k
The agentic SEO stack - context over prompts
schlessera
0
980
4 Signs Your Business is Dying
shpigford
187
23k
sira's awesome portfolio website redesign presentation
elsirapls
0
470
Typedesign – Prime Four
hannesfritz
42
3.2k
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
630
エンジニアに許された特別な時間の終わり
watany
109
250k
Why You Should Never Use an ORM
jnunemaker
PRO
61
10k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
330
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.4k
Transcript
Humble Object Pattern な話 Roppongi.unity #1 2019/02/21 Roppongi.unity #1 2019/02/21
いもです いも(@adarapata) ゲー ムクライアントエンジニア adarapata.com Roppongi.unity #1 2019/02/21
ご注意 2019/1/23 にGotanda.unity #10 で発表した「 どこから始めるUnity Test」 の時間切れで話せなかった後半部分にフォー カスした内容です。 https://speakerdeck.com/adarapata/dokokarashi-meruunity-test
なので前回と若干被る話が多いのでご了承ください。 Roppongi.unity #1 2019/02/21
今日の話 Humble Object Pattern について Roppongi.unity #1 2019/02/21
前提 みんなテストが書きたくて手が震えている Roppongi.unity #1 2019/02/21
テストしにくさの元 密結合 static なインスタンス 入力イベントが絡む処理 UI が絡む処理 ファイル、DB などの外部リソー スが絡む処理
etc.. 実際問題、 どう綺麗に書いてもテストしにくい部分は出てくる Roppongi.unity #1 2019/02/21
テストピラミッド。 上位に行くほど難易度が高い Roppongi.unity #1 2019/02/21
コスト高いのでテスト避けたい わかる 時にはそういう判断も必要かもしれない 書かない ≠ 書けない 書けない理由は明らかにすべき。 ピラミッドの境界を跨ぐような処理を分割していく Roppongi.unity #1
2019/02/21
Humble Object Pattern とは テストしやすいものとしにくいものを住み分ける実装パター ン テストしにくいものの実装をHumble( 控え目) にする 多分初出は
xUnit Patterns http://xunitpatterns.com/Humble Object.html クリー ンアー キテクチャ本にも載ってたので有名かも Roppongi.unity #1 2019/02/21
public class PlayerUnit : MonoBehaviour { [SerializeField] private float _speed
= 1F; void Update() { var horizontal = Input.GetAxis("Horizontal"); var vertical = Input.GetAxis("Vertical"); Move(new Vector3(horizontal, vertical)); } private void Move(Vector3 direction) { transform.position += direction * _speed; } } きちんと任意の方向に動くかテストを実装したい Roppongi.unity #1 2019/02/21
書きにくさポイント 入力が絡むので書きにくい MonoBehavior の機能に依存しているので書きにくい SerializeField も同様 でも移動する部分は書きたい 書きやすいものと書きにくいものを切り分ける。 Unity における書きにくいものは大体MonoBehaviour
絡みなのでそこか ら切り出す。 Roppongi.unity #1 2019/02/21
public interface IPlayerUnit { float Speed { get; } Vector3
Position { get; set; } } // MonoBehavior 成分を0にしたけど、 移動ロジックを持つクラス public class PlayerUnitController { private readonly IPlayerUnit _unit; public PlayerUnitController(IPlayerUnit unit) { _unit = unit; } public void Move(Vector3 direction) { _unit.Position += direction * _unit.Speed; } } テストを書きにくいMonobehavior からロジックを抽出する Roppongi.unity #1 2019/02/21
public class PlayerUnitHumble : MonoBehaviour, IPlayerUnit { [SerializeField] private float
_speed = 1F; private PlayerUnitController _controller; public float Speed => _speed; public Vector3 Position { get => transform.position; set => transform.position = value; } void Start() => _controller = new PlayerUnitController(this); void Update() { var horizontal = Input.GetAxis("Horizontal"); var vertical = Input.GetAxis("Vertical"); _controller.Move(new Vector3(horizontal, vertical)); } } Roppongi.unity #1 2019/02/21
変更点 移動処理の詳細と、Monobehavior が離れた 具体的な処理は PlayerUnitController に任せるようになった テストしやすいものとしにくいものに分かれた ピラミッドの境界が明確になった 切り分けられたので、 移動処理のテストも書ける。
入力のテストはやらない! 移動処理を行う側はインタフェー スだけ見ているので、 差し替えが楽。 Roppongi.unity #1 2019/02/21
IPlayerUnit は状況に応じて差し替えられる Roppongi.unity #1 2019/02/21
IPlayerUnit は状況に応じて差し替えられる Roppongi.unity #1 2019/02/21
テストコー ド public class PlayerUnitTest { // テスト用のいい感じモック public class
MockPlayerUnit : IPlayerUnit { public float Speed { get; set; } public Vector3 Position { get; set; } } [Test] public void PlayerUnitMove() { var unit = new MockPlayerUnit { Speed = 5, Position = Vector3.zero }; var controller = new PlayerUnitController(unit); controller.Move(Vector3.up); Assert.AreEqual(new Vector3(0,5F,0), unit.Position); } } Roppongi.unity #1 2019/02/21
まとめ テストしにくい部分は発生する テストしにくいところとしやすいところを分けて、 書ける領域を増 やす Humble Object はそれらを切り分ける Roppongi.unity #1
2019/02/21