質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

2回答

602閲覧

インターフェースを実装するべき側の判断について

hogefugapiyo

総合スコア3302

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

1グッド

1クリップ

投稿2020/01/22 11:15

お世話になっております。

現在、インターフェースを用いてプレイヤーがアイテムを拾えるかどうかの機能を作成しています。
機能自体は問題なく作ることができたのですが、ここで疑問となったのが、インターフェースを実装すべき側はどちらなのかということです。

例えば、下記の条件があったとします
・【プレイヤー】は、【フルーツ】を拾える。

この時に

  1. プレイヤー側にフルーツを拾うことができる IItemGettable のようなインターフェースを実装するべきなのか
  2. フルーツ側に、拾われることができる IGettable というインターフェースを実装するべきなのか

#サンプル #1 プレイヤー側に実装する場合

IItemGettable

cs

1using UnityEngine; 2 3public interface IItemGettable { 4 void PickUp(GameObject obj); 5}

Player.cs

cs

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5 public class Player : MonoBehaviour, IItemGettable { 6 public void PickUp(GameObject obj) { 7 Debug.Log(obj.name + "を手に入れた"); 8 } 9 } 10

Fruits

cs

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Fruits : MonoBehaviour { 6 7 private void OnCollisionEnter(Collision collision) { 8 var target = collision.gameObject.GetComponent<IGettable>(); 9 10 if (target != null) { target.Pickup(gameObject); } 11 } 12 13} 14

#サンプル #2 フルーツ側に実装する場合

IGettable

cs

1public interface IGettable { 2 void Get (); 3}

Player.cs

cs

1void OnTriggerEnter (Collider collision) { 2 var iGettable = collision.GetComponent<IGettable>(); 3 4 if (iGettable != null) { 5 iGettable.Get(); 6 Debug.Log("アイテムを取得しました"); 7 } 8 9}

Fruits.cs

cs

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5 6public class Gem : MonoBehaviour, IGettable { 7 public void Get () { 8 GetComponent<Renderer>().enabled = false; 9 Debug.Log("自身を消す(取得された)"); 10 } 11} 12

サンプル間で多少のコードの差はあるとしても、どちら側が主体となるべきなのか、どちら側が処理を判断すべきなのか。
インターフェースを実装する際の考え方など、ご教授いただければ幸いです。

Hawn👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2020/01/22 12:04

両方です。 Pickup の引数が GameObject ですが、GameObject なら何でも拾えるわけではないと思います。ならば拾われる対象ということを示すために拾われるオブジェクトにインターフェースを実装するのが良いでしょう。 また拾われたオブジェクトはプレイヤーの持ち物としてリストに入るはずです。ならばプレイヤーへの操作が必要なのでプレイヤーは操作されるためのインターフェースを実装するのが良いと思います。 ただし、物を拾えるのがプレイヤーのみである場合、プレイヤーはインターフェースを実装する必要はありません。プレイヤークラスであることがすでにインターフェースであるからです。
hogefugapiyo

2020/01/24 00:29

ご回答ありがとうございます。 プレイヤーが一人である場合はたしかに一意であるという内容、当たり前の話かもしれませんが改めて聞いてすごく納得する内容でした。
guest

回答2

0

ベストアンサー

こんにちは。

この情報だけだとどんな回答をしても正当化できてしまいますが、今回は一般論に限って述べます。

結論から言うと、お互いのオブジェクトの関係が「一対多」であると仮定したとき、「多」のオブジェクト側にインターフェースを実装します。
具体例をあげると、

  • 「一人の」プレイヤーが、「様々な」フルーツを拾える状況である場合、フルーツ側にインターフェースを実装し、プレイヤーは唯一つのインターフェースにアクセスすることで、どのようなフルーツでも拾えるようにします。
  • 「様々な形態の」プレイヤーが、「とある」フルーツに対して拾うアクションを起こせるのであれば、プレイヤー側にインターフェースを実装します。

実際には、複雑化してくると「多対多」の関係になる場合が多く、その場合では「両方にそれぞれのインターフェースを実装する」ことになります。
プレイヤーは「アイテムを拾うことができる」性質を持ち、アイテムは「拾われることができる」性質を持ちます。
最終的に、「拾う者は、拾えるモノを拾える」という、禅問答のような定義に落ち着くのです。

インターフェースは性質の定義であり、オブジェクトが特定の機能を持つことを保証するものです。
多数のオブジェクトを横断して「とある性質を持つ」ものを同一視できることがインターフェースを利用する最大の目的になるので、「一対多の関係性」を考慮してインターフェース設計を行ってください。

投稿2020/01/23 01:07

tamoto

総合スコア4110

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hogefugapiyo

2020/01/24 00:26

わかりやすい解説を頂きましてありがとうございます。 確かに禅問答のようにどちらにどちらをと繰り返していたので理解しやすい内容で助かりました。 それぞれの要素の関係性を考えて今後作成していきたいと思います。ありがとうございました。
guest

0

どちらが良いかは全体の設計次第なのでこれだけの情報では答えようがありません。
が、質問を見てこの記事を思い出しましたので参考にどうぞ。

[CEDEC 2011]AIに命を。「ぽかぽかアイルー村」のアフォーダンス指向によるAI事例と「ARMORED CORE V」の三次元的な移動経路検索

投稿2020/01/22 11:22

編集2020/01/22 11:23
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hogefugapiyo

2020/01/24 00:27

興味深い内容のURLを共有いただきありがとうございます。 アフォーダンス志向という内容はとても興味深く、ある種わかりやすい内容だったのでとてもありがたいです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問