【C#】if文だらけのUI制御をスッキリ!ポリモーフィズム活用術
はじめに
みなさん、if文やswitch文が大量に並んだコードを見て「うわ…読みづらい」と思ったことはありませんか?
特に、ゲームのUI制御などでは、画面が増えるたびにif-else
やswitch
が膨れ上がりがちです。
そこで今回は、その悩みを少しでも解決できる方法を1つ紹介します。
具体例として、以下のようなUI制御コードをリファクタリングしながら説明します。
① よくある if-else だらけのUI制御
以下は典型的なif-else
でUIを制御するコードです。
public enum GameUIType
{
Start,
GamePlay,
GameOver,
}
/// <summary>
/// UIを表示するクラス
/// </summary>
public class GameUIPresenter
{
private StartUI startUI = new StartUI();
private GamePlayUI gamePlayUI = new GamePlayUI();
private GameOverUI gameOverUI = new GameOverUI();
public void ShowUI(GameUIType uIType)
{
if (uIType == GameUIType.Start)
{
startUI.Show();
}
else if (uIType == GameUIType.GamePlay)
{
gamePlayUI.Show();
}
else if (uIType == GameUIType.GameOver)
{
gameOverUI.Show();
}
}
}
UIごとのクラス
public class StartUI
{
public void Show() => Debug.Log("スタートUIが表示される");
}
public class GamePlayUI
{
public void Show() => Debug.Log("ゲームプレイUIが表示される");
}
public class GameOverUI
{
public void Show() => Debug.Log("ゲームオーバーUIが表示される");
}
問題点
この実装では、UIの種類が増えるたびにif-else
文が増加していきます。
たとえば、リザルト画面やポーズ画面を追加した場合、ShowUI
メソッド内にさらに条件分岐が必要になります。
② ポリモーフィズムでスッキリ書き換え
そこで、ポリモーフィズム(多態性)を活用して、条件分岐を削減します。
改善後のコード
public abstract class GameUIBase
{
public abstract void Show();
public abstract GameUIType GetUIType();
}
public class StartUI : GameUIBase
{
public override GameUIType GetUIType() => GameUIType.Start;
public override void Show() => Debug.Log("スタートUIが表示される");
}
public class GamePlayUI : GameUIBase
{
public override GameUIType GetUIType() => GameUIType.GamePlay;
public override void Show() => Debug.Log("ゲームプレイUIが表示される");
}
public class GameOverUI : GameUIBase
{
public override GameUIType GetUIType() => GameUIType.GameOver;
public override void Show() => Debug.Log("ゲームオーバーUIが表示される");
}
プレゼンタークラス
public class GameUIPresenter
{
private GameUIBase[] gameUIBaseArray;
public void Initialize()
{
gameUIBaseArray = new GameUIBase[]
{
new StartUI(),
new GamePlayUI(),
new GameOverUI()
};
}
public void ShowUI(GameUIType uIType)
{
foreach (var gameUI in gameUIBaseArray)
{
if (gameUI.GetUIType() == uIType)
{
gameUI.Show();
return;
}
}
}
}
改善ポイントまとめ
- UIごとの処理を**共通の抽象クラス(GameUIBase)**にまとめた
- プレゼンター側の
if-else
をループとポリモーフィズムだけで簡潔に記述 - 新しいUIを追加する場合、GameUIBaseを継承したクラスを作成するだけ
おわりに
今回紹介したように、ポリモーフィズムを使えば、if-else
の増殖を防ぎ、コードの保守性と拡張性が大きく向上します。
UI制御だけでなく、似たような分岐が増えそうな場面では、ぜひ活用してみてください!