24
インターフェイス実装の活用例 ActionScriptAiming大阪スタジオ ソフトウェアエンジニア 松田理 2012/12/12

インターフェイス実装の活用例 AS編

Embed Size (px)

Citation preview

Page 1: インターフェイス実装の活用例 AS編

インターフェイス実装の活用例ActionScript編

Aiming大阪スタジオ

ソフトウェアエンジニア 松田理孝

2012/12/12

Page 2: インターフェイス実装の活用例 AS編

Yoshitaka Matsuda

– Aiming大阪スタジオ

– 新入社員、1年目

– C# → ActionScript

• 大阪では異例の経歴

– 趣味はイラスト描き →

Page 3: インターフェイス実装の活用例 AS編

突然ですが

• for(..) { switch(..) { case.. case.. case.. } }

– っていうソースコード

うっかり、書いちゃったりしますか– 行数多い

– 見た目が悪い

– よくわからん

• 綺麗にしたい!!

→インターフェイス使えば解決できる

Page 4: インターフェイス実装の活用例 AS編

インターフェイス

• 英語で界面や接触面、中間面などといった意味を持ち、転じてコンピュータと周辺機器の接続部分を表すようになった。(出典:Wikipedia)

• ユーザインターフェイスとか

• 電気のコンセントとかUSBとか

Page 5: インターフェイス実装の活用例 AS編

プログラムのインターフェイス

• 内部はわからない

• 振る舞いはわかる

→とある型の引数を取って、とある型を返す

→引数の数も当然一緒

→名前も一緒じゃないといけない

• そこまで一緒なら、継承・オーバーライドでよくね?

Page 6: インターフェイス実装の活用例 AS編

家電に例える

どちらも食品を入れられる何か

→でも実際、動作は全く別物!!

Page 7: インターフェイス実装の活用例 AS編

クラスの継承とはどういうことか

1. 食べ物を入れる箱(空間)を用意する

2. 箱に扉の機能を追加する

3. さらに冷やす機能追加して冷蔵庫にする

4. 上の箱に温める機能を追加してレンジ

→箱とドアは、レンジと冷蔵庫で共有している

Page 8: インターフェイス実装の活用例 AS編

クラスの継承とはどういうことか

• 冷蔵庫は扉、両開きがいいです

– 扉クラスに両開きかどうか判定させる?

– 両開き扉クラスを作る?

• 冷蔵庫の箱にはペットボトル入れられます

– レンジに入れられないものとかどうしよう?

– 箱の内部で逐一判定?

→スパゲティコード化

Page 9: インターフェイス実装の活用例 AS編

インターフェイスにすると?

• インターフェイスの用意

– モノを出し入れできる扉インターフェイス

→扉を介して、入れたり出したりする振る舞いは

冷蔵庫でもレンジでも一緒である

→実際、両開きかどうかは実装に任せる

– 冷蔵庫は両開き実装

– レンジは片開き実装

Page 10: インターフェイス実装の活用例 AS編

外部から見たら

• 扉インターフェイスがある

→これを介せばモノが出し入れできるんだろう

• 詳細はよくわからないけど、出し入れできるという振る舞いはわかる

Page 11: インターフェイス実装の活用例 AS編

実際に定義してみる

• 等価比較の振る舞いをする

Page 12: インターフェイス実装の活用例 AS編

実装してみる

• 内部がintだけのダミークラス

– このクラスだけの等価比較の実装

Page 13: インターフェイス実装の活用例 AS編

使ってみる

• 当然、こうなる

• あ、やっぱDummyとintでもtrueにしたい!– Dummyのequalsを変えるだけでいい

→ほかに影響は出ない!!

Page 14: インターフェイス実装の活用例 AS編

Tupleの等価比較

• 一時的に、値をセットにしたい時に使う

– 型とか自由、単にペアやトリオにしたいだけ

– 2変数のタプル作ってみる

Page 15: インターフェイス実装の活用例 AS編

Tupleの等価比較

• IEquals.equalsの実装

– 各要素がIEqualsを実装していれば、そちら優先

→要素の実際の型が分からなくても比較できる!

Page 16: インターフェイス実装の活用例 AS編

for-switchのパターン

• ゲームのスキルを考える

– 使用できる場所を制限したい場合を考える

• バトルで使えるか

• フィールドで使えるか

→とりあえず、Switch文で場合分けしてみる

Page 17: インターフェイス実装の活用例 AS編

for-switchのパターン

• Scene.Townが増えたらどうなるの?

• アイテムとか増えたらどうなるの?

Page 18: インターフェイス実装の活用例 AS編

for-switch撲滅する

→まずインターフェイスを用意

– 使用できるかの判定関数

– 実際使用したときの処理

を定義する(実装はしない)

Page 19: インターフェイス実装の活用例 AS編

for-switch撲滅する

– 実際に判定を行う処理を実装

• Usable.OnField

• Usable.OnBattle

Page 20: インターフェイス実装の活用例 AS編

for-switch撲滅する

Itemにも実装しちゃう

Page 21: インターフェイス実装の活用例 AS編

for-switch撲滅する

– itemも同じくitem.isUsable(..)で判定できる

• ソースコードの重複なども無くすことができる

Usable.OnFieldが呼ばれる

Page 22: インターフェイス実装の活用例 AS編

何が嬉しいか

• ItemやSkillで判定式を共有できる– Usable.OnField、Usable.OnBattle

• 判定式の追加が容易– Usable.OnTownなど、後から追加できる

– 他の部分に変更を出さない

• 無駄なswitch文、if文を極力なくせる– 実際のインスタンスを入れ替えている

• if文の判定を間違えることがない– バグが起きにくい

Page 23: インターフェイス実装の活用例 AS編

インターフェイスを使うに当たって

• インターフェイスはオブジェクトの関数・プロパティを定義するヘッダーファイルではない

– ISampleがSampleだけに使われる想定があってはならない

• インターフェイスは具体的でなくていい

– 1つのインターフェイスにメソッドがたくさん定義されるような状態であれば、分離すること

Page 24: インターフェイス実装の活用例 AS編

さいごに

• とにかく継承はできる限りやめましょう

• クラスは疎結合にしましょう

– 仕様変更に耐えられるように

– 仕様追加に耐えられるように

– あとから参加した人が見やすいように

– 機能を小分けしてチーム開発しやすいように

• 「ここの処理、変更してほしいんですけど」– 変更部分のみを修正すれば、周りに影響が出ない!

» ってのが理想……