目次
SOLID原則を勉強する その1~単一責任の原則 (SRP)~
SOLID原則を勉強する その2~オープン・クローズド原則(OCP)~
SOLID原則を勉強する その3~リスコフの置換原則(LSP)~
SOLID原則を勉強する その4~インターフェース分離の原則(ISP)~ ←いまここ
SOLID原則を勉強する その5~オ 依存性逆転の原則(DIP)~
前置き
書籍を読んだり、ググったりして、自分に分かりやすいようにまとめた記事です。
より詳しく知りたい方は、下記の参考文献を読んでみてください。
参考文献
Clean Architecture 達人に学ぶソフトウェアの構造と設計 | Amazon
Adaptive Code ~ C#実践開発手法 | Amazon
C#の設計の基本【SOLID原則】まとめ
Unity開発で使える設計の話+Zenjectの紹介
C# で SOLID の原則に違反する危険性
インターフェース分離の原則(ISP)
クライアントが利用しないメソッドの実装を強制してはいけない
「不必要なメソッドなのに実装しなければならない」を防ぐ
インターフェースには最小限のものだけ定義するべき
コード例
それぞれの敵の行動パターンを管理する Shadow クラス、 Gigas クラス、 DarkInferno クラスを作成します。
(敵の元ネタはキングダムハーツです。分からない人はすみません…)
それぞれのクラスは、以下の行動を行います。
Shadow
Gigas
DarkInferno
攻撃
○
○
○
歩行
○
○
×
飛行
×
○
○
before
IEnemy インターフェースを用意
敵クラスは全てこのインターフェースを実装する
IEnemy.cs
public interface IEnemy
{
void Attack();
void Walk();
void Fly();
}
Shadow.cs
using UnityEngine;
public class Shadow : IEnemy
{
public void Attack()
{
Debug.Log("シャドウの攻撃");
}
public void Fly()
{
// 空を飛ばないので、このメソッドでは何もしない
}
public void Walk()
{
Debug.Log("シャドウが歩いて移動");
}
}
Gigas.cs
using UnityEngine;
public class Gigas : IEnemy
{
public void Attack()
{
Debug.Log("ギガースの攻撃");
}
public void Fly()
{
Debug.Log("ギガースが空を飛ぶ");
}
public void Walk()
{
Debug.Log("ギガースが歩く");
}
}
DarkInferno.cs
using UnityEngine;
public class DarkInferno : IEnemy
{
public void Attack()
{
Debug.Log("ダークインフェルノの攻撃");
}
public void Fly()
{
Debug.Log("ダークインフェルノが空を飛んで移動");
}
public void Walk()
{
// 歩かずに常に空を飛んで移動するので、このメソッドでは何もしない
}
}
ダメなところ
Gigas クラスは全てのメソッドを必要としているが…
Shadow クラスは Fly メソッドは不要(空を飛ばないから)
DarkInferno クラスは Walk メソッドは不要(歩かないから)
不要なメソッドの実装を強要している
新たな敵クラスを実装するときや、メソッドを呼び出すクライアント側も混乱してしまう
After
IEnemy インターフェースを IAttack, IWalk, IFly の各インターフェースに分離
敵クラスは必要なインターフェースを選んで実装する
IAttack.cs
public interface IAttack
{
void Attack();
}
IWalk.cs
public interface IWalk
{
void Walk();
}
IFly.cs
public interface IFly
{
void Fly();
}
Shadow.cs
using UnityEngine;
public class Shadow : IAttack, IWalk
{
public void Attack()
{
Debug.Log("シャドウの攻撃");
}
public void Walk()
{
Debug.Log("シャドウが歩いて移動");
}
}
Gigas.cs
using UnityEngine;
public class Gigas : IAttack, IFly, IWalk
{
public void Attack()
{
Debug.Log("ギガースの攻撃");
}
public void Fly()
{
Debug.Log("ギガースが空を飛ぶ");
}
public void Walk()
{
Debug.Log("ギガースが歩く");
}
}
DarkInferno.cs
using UnityEngine;
public class DarkInferno : IAttack, IFly
{
public void Attack()
{
Debug.Log("ダークインフェルノの攻撃");
}
public void Fly()
{
Debug.Log("ダークインフェルノが空を飛んで移動");
}
}
良いところ
不要なインターフェースの実装がなくなった
終わりに
もし変なところがあったら教えて下さい。
(特にクラス図とか…)
↧