SlideShare a Scribd company logo
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

More Related Content

What's hot (20)

PDF
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
Takuto Wada
 
PDF
それはYAGNIか? それとも思考停止か?
Yoshitaka Kawashima
 
PDF
リレーショナルな正しいデータベース設計
Mikiya Okuno
 
PDF
計算機アーキテクチャを考慮した高能率画像処理プログラミング
Norishige Fukushima
 
PPTX
世界一わかりやすいClean Architecture
Atsushi Nakamura
 
PDF
例外設計における大罪
Takuto Wada
 
PDF
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
Takuto Wada
 
PDF
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
Koichiro Matsuoka
 
PDF
DDDとクリーンアーキテクチャでサーバーアプリケーションを作っている話
JustSystems Corporation
 
PDF
劇的改善 Ci4時間から5分へ〜私がやった10のこと〜
aha_oretama
 
PDF
TLS, HTTP/2演習
shigeki_ohtsu
 
PPT
ジェネリクスの基礎と クラス設計への応用
nagise
 
PPTX
イベント駆動プログラミングとI/O多重化
Gosuke Miyashita
 
PDF
Git flowの活用事例
Hirohito Kato
 
PDF
雑なMySQLパフォーマンスチューニング
yoku0825
 
PDF
Dockerからcontainerdへの移行
Kohei Tokunaga
 
PDF
1-2-2 プラン・お支払い設定
freee株式会社
 
KEY
やはりお前らのMVCは間違っている
Koichi Tanaka
 
PDF
いつやるの?Git入門 v1.1.0
Masakazu Matsushita
 
PDF
ソーシャルゲームのためのデータベース設計
Yoshinori Matsunobu
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
Takuto Wada
 
それはYAGNIか? それとも思考停止か?
Yoshitaka Kawashima
 
リレーショナルな正しいデータベース設計
Mikiya Okuno
 
計算機アーキテクチャを考慮した高能率画像処理プログラミング
Norishige Fukushima
 
世界一わかりやすいClean Architecture
Atsushi Nakamura
 
例外設計における大罪
Takuto Wada
 
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
Takuto Wada
 
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
Koichiro Matsuoka
 
DDDとクリーンアーキテクチャでサーバーアプリケーションを作っている話
JustSystems Corporation
 
劇的改善 Ci4時間から5分へ〜私がやった10のこと〜
aha_oretama
 
TLS, HTTP/2演習
shigeki_ohtsu
 
ジェネリクスの基礎と クラス設計への応用
nagise
 
イベント駆動プログラミングとI/O多重化
Gosuke Miyashita
 
Git flowの活用事例
Hirohito Kato
 
雑なMySQLパフォーマンスチューニング
yoku0825
 
Dockerからcontainerdへの移行
Kohei Tokunaga
 
1-2-2 プラン・お支払い設定
freee株式会社
 
やはりお前らのMVCは間違っている
Koichi Tanaka
 
いつやるの?Git入門 v1.1.0
Masakazu Matsushita
 
ソーシャルゲームのためのデータベース設計
Yoshinori Matsunobu
 

Recently uploaded (8)

PDF
[Hardening Designers Confernece 2025]ランサムウェアでの見えざるログ・見えるログ
kataware
 
PDF
20250710_Devinで切り拓くDB革命_〜価値創出に集中せよ〜.pdf
Masaki Yamakawa
 
PDF
PostgreSQL18新機能紹介(db tech showcase 2025 発表資料)
NTT DATA Technology & Innovation
 
PDF
20250711_日本IBM ミドルウエア・ユーザー研究会(JIMUC)総会_中村会長資料.pdf
ChikakoInami1
 
PDF
Hyperledger Fabric最新v3.x系での機能強化、変更点にキャッチアップ!
LFDT Tokyo Meetup
 
PDF
Hyperledger Fabric公式サンプル fabric-samples徹底解説
LFDT Tokyo Meetup
 
PDF
プライバシ保護のためのインターネットアーキテクチャの進化 (2025-07-11)
Jun Kurihara
 
PDF
人気ブロックチェーン基盤「Hyperledger Fabric」最新版を動かしてみた!
LFDT Tokyo Meetup
 
[Hardening Designers Confernece 2025]ランサムウェアでの見えざるログ・見えるログ
kataware
 
20250710_Devinで切り拓くDB革命_〜価値創出に集中せよ〜.pdf
Masaki Yamakawa
 
PostgreSQL18新機能紹介(db tech showcase 2025 発表資料)
NTT DATA Technology & Innovation
 
20250711_日本IBM ミドルウエア・ユーザー研究会(JIMUC)総会_中村会長資料.pdf
ChikakoInami1
 
Hyperledger Fabric最新v3.x系での機能強化、変更点にキャッチアップ!
LFDT Tokyo Meetup
 
Hyperledger Fabric公式サンプル fabric-samples徹底解説
LFDT Tokyo Meetup
 
プライバシ保護のためのインターネットアーキテクチャの進化 (2025-07-11)
Jun Kurihara
 
人気ブロックチェーン基盤「Hyperledger Fabric」最新版を動かしてみた!
LFDT Tokyo Meetup
 
Ad

Humble Object Patternな話