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

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

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

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

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

Unity

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

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Q&A

解決済

2回答

1738閲覧

殆どの処理は同じだが、一部だけ処理が違う場合どのような構成で書けばよいのでしょう?

mushipan0929

総合スコア56

C#

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

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

Unity

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

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

0グッド

1クリップ

投稿2022/01/16 07:38

編集2022/01/19 11:41

-- 回答者様から目的が不鮮明とのご指摘を受けましたので、下記により具体的な質問を付け加えました。--

殆どの処理は同じだが、一部だけ処理が違う場合どのような構成で書けばよいのでしょう?
下に良く使う方法を2つ挙げました。
2,3種類の場合は2を使い、それ以上になると1を使っています。
ですがどちらにしろ面倒な事には変わりなくもっと良い方法があれば御教授願いたいです。

あと余談ですが、プレビュー画面の文字が全て黒色になっているのですがこれは私だけですか?

1: 共通している処理を基底クラスにして違う部分を派生クラスに記載する
〇: それぞれの派生クラスの中に処理が書けるので見て分かりやすい
×: これらを管理する時に一つずつOverrideされた関数を呼ぶのが面倒。宣言も面倒。

C#

1public class Main : MonpBehaviour 2{ 3 private ClassA classA; 4 private ClassB classB; 5 private ClassC classC; 6 7 private void Start() { 8 classA = new ClassA(); 9 classB = new ClassB(); 10 classC = new ClassC(); 11 } 12 13 private void Update() { 14 classA.ManagedUpdate(); 15 classB.ManagedUpdate(); 16 classC.ManagedUpdate(); 17 } 18} 19 20public class BaseClass { 21 protected void Hoge() { 22 } 23 24 public virtual void ManagedUpdate() { 25 } 26} 27 28public class ClassA : BaseClass { 29 public override void ManagedUpdate() { 30 } 31} 32public class ClassB : BaseClass { 33 public override void ManagedUpdate() { 34 } 35} 36public class ClassC : BaseClass { 37 public override void ManagedUpdate() { 38 } 39}

2:すべて同じクラスを使用し、Enumの値によって処理を変える
〇: 呼び出しは簡単。
×: ManagedUpdateの中身がすごく長くなる

public class Main : MonpBehaviour { private BaseClass[] baseClasses = new BaseClass[3]; private void Start() { baseClass[0] = new BaseClass(TYPE.A); baseClass[1] = new BaseClass(TYPE.B); baseClass[2] = new BaseClass(TYPE.C); } private void Update() { foreach(BaseClass baseClass in baseClasses) { baseClass.ManagedUpdate(); } } } public class BaseClass { private TYPE type; public BaseClass(TYPE type) { this.type = type; } private void Hoge() { } public void ManagedUpdate() { switch(type) { // それぞれに異なる処理を書く case TYPE.A: break; case TYPE.B: break; case TYPE.C: break; } } } public enum TYPE { A, B, C }

-----------------------------追記-------------------------------
・条件
プレイヤーはDキーを押すとMoveUIが頭上に出現する
プレイヤーはAキーを押すとStopUIが頭上に出現する
一度に出せるUIは1種類/1つのみ
!___既に同じUIが出ている場合は何も起こらない
!___違うUIが出ている場合はそのUIを消してから新しいUIを出す
各UIは出現/消滅時に演出をする

UIを扱うPlayerがどうしても冗長になってしまっています。
また今後プレイヤーが扱うUIの種類が増えるとさらに長くなってしまいます。
どうにかここをシンプルに出来ないでしょうか?

public class UiManagement { private MoveUI[] moveUIs; private StopUI[] stopUIs; public MoveUI FindNotUseMoveUI() { foreach(MoveUI moveUI in moveUIs) { if (moveUI.IsEnable == false) return moveUI; } return null; } public StopUI FindNotUseStopUI() { foreach (StopUI stopUI in stopUIs) { if (stopUI.IsEnable == false) return stopUI; } return null; } } public class Player : MonoBehaviour { private UiManagement uiManagement; private MoveUI moveUI; private StopUI stopUI; private void Update() { if(Input.GetKeyDown(KeyCode.A)) { if (stopUI != null) return; if (moveUI != null) { moveUI.Disable(); moveUI = null; } stopUI = uiManagement.FindNotUseStopUI(); stopUI.Enable(); } if (Input.GetKeyDown(KeyCode.D)) { if (moveUI != null) return; if (stopUI != null) { stopUI.Disable(); stopUI = null; } moveUI = uiManagement.FindNotUseMoveUI(); moveUI.Enable(); } if (moveUI != null) moveUI.ManagedUpdate(); else if (stopUI != null) stopUI.ManagedUpdate(); } } public class MoveUI : BaseUI { public void ManagedUpdate() { Debug.Log("MoveUI出現中"); } } public class StopUI : BaseUI { public void ManagedUpdate() { Debug.Log("StopUI出現中"); } } public class BaseUI { public bool IsEnable { get; private set; } public void Enable() { IsEnable = true; } public void Disable() { IsEnable = false; } }

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

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

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

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

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

gentaro

2022/01/16 07:55

「処理」だけに着目するなら、「ちゃんと動くならどんな設計でもOK」という回答にしかならない。「ちゃんと動く」ものに対して「良い、悪い」という判断がしたいなら、それはどんな基準で考えるべきなのかの提示がないと無理。 例えばオブジェクト指向設計的に良いのか悪いのか、という話なら、こんな抽象的な例ではクラス分けが適切なのかわかるわけがないので、回答不能。 「関数を呼ぶのが面倒。宣言も面倒。」みたいなレベルで考えるなら、あなたが一番楽なやり方が正解、という話にしかならないので、他者は答えられない。
ikapy

2022/01/16 08:42

gentaroさんに賛同します。
mushipan0929

2022/01/16 10:14

確かに具体性が足りませんでした。申し訳ない。 追記しましたので再度ご確認をお願いいたします。
guest

回答2

0

ベストアンサー

class BaseUI ← こいつは何のために存在しているんだろうか?

継承を MoveUI, StopUI に「Enable関連の実装コードをコピペする手段」としか捉えていないのであれば,「ポリモフィズム」とか「Is-a 関係」とかそういう話をちょっと学んでみてはどうか.

投稿2022/01/18 08:04

fana

総合スコア11634

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

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

fana

2022/01/18 08:10

Player のコードを見て,そんなことを思った. MoveUI だの StopUI だのいう型を扱う必要ないんじゃないかな.BaseUI 型を扱う形に書けないのか?ってのを考えてみては?
mushipan0929

2022/01/19 01:08

>> 継承を MoveUI, StopUI に「Enable関連の実装コードをコピペする手段」としか捉えていない 確かに継承は重複した内容を一々書かなくても良くなる機能程度にしか考えていませんでしたが、そうではないようですね。 ポリモフィズム, Is-a関係について調べより良く使っていきたいと思います。
fana

2022/01/19 02:41

今の状態だと, 【BaseUIというクラスを削除して, MoveUI と StopUI それぞれには Enable関係の全く同じ実装を書く】 という形に変えてしまっても全く問題ない感じですよね. 「BaseUI から派生したやつ(:BaseUIを継承した型)であれば,そいつにはEnable関係の プロパティ/メソッド が存在している(→から,それを使える)」 という事柄を 利用 する形を考えるならば,継承に別の価値を見出せるでしょう.
guest

0

私も既存の処理で似たような処理をうまく抽象化できていないために
新機能の実装時の修正漏れや
ごちゃごちゃしすぎた共通処理の理解に時間がかかりすぎてしまう
ことがよく起こっています。

現場ではあまり問題意識も持っていなかったりしますので、同じ問題を持っている人と意見交換したかったりします。

次のような記事も参考になりますでしょうか。

新人エンジニアが初めてC#のデリゲートを使った時の話
https://tech.yayoi-kk.co.jp/entry/2019/12/15/070000

投稿2022/01/16 08:30

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

mushipan0929

2022/01/16 09:18

デリゲートはコールバックとして使っていましたが、共通化も可能なんですね... ありがとうございます、参考になりました。
Zuishin

2022/01/16 11:58

この例はコールバックです。
退会済みユーザー

退会済みユーザー

2022/01/16 14:00

ごめんなさい、質問内容と違うことを入力してしまったのですね・・
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問