目的
エンジニア2年目で、コードの書き方に迷うことが多くなってきたので、本にて学習した。
背景
switch文などの条件分岐でコードが読みづらくなることが多くある。
そんな時に、デザインパターンの一種であるストラテジパターンが使用できる、とのこと。
本文
前提
ゲーム開発を行なっており、技を定義したい。
技
- ファイア
- 紫電
- 地獄の業火
技に設定されている値
- 名前:name
- 消費魔法力:costMagicPoint
- 攻撃力:attackPower
- 消費TP:costTechnicalPoint
魔法の種類を定義
enum MagicType{
fire,
shiden,
hellFire
}
やりたいこと
技によって、名前や消費魔法力などを定義したい。
単純に考えるのであれば、switch case文を用いて設定する。
技がfireの時 : nameはファイア、costMagicPointは2、attackPowerは20、costTechnicalPointは0。
しかし、上記ではfire、shiden、hellFire、、、(続く)となった時に、ロジックが煩雑になっていく。
そこでinterfaceを入れることで、ロジックを見やすく見通しの良いものにしたい。
1.切り替えたい機能の定義
interface Magic{
String name();
int costMagicPoint();
int attackPower();
int costTechnicalPoint();
}
2.各魔法にinterfaceを実装する
// この場合は、ファイアの実装
class Fire implements Magic{
private final Member member;
// 初期化
Fire(final Member member){
this.member = member;
}
public String name(){
return "ファイア";
}
public int costMagicPoint(){
return 2;
}
public int attackPower(){
return 20 + (int)(member.level * 0.5);
}
public int costTechnicalPoint(){
return 0;
}
}
//上記を紫電、地獄の業火に関しても作成する。
3.switchの代わりにMapで切り替える
final Map<Magic Type, Magic> magics = new HashMap<>();
// ファイア型のインスタンスを生成
final Fire fire = new Fire(member);
…
// fire型がきた時には、上記のfire型のインスタンスを返す。
magics.put(MagicType.fire,fire);
…
void magicAttack(final MagicType magicType){
// magicTypeには、fire、shiden、hellFireなどが入る。
final Magic usingMagic = magics.get(magicType);
// メソッドの定義
showMagicName(usingMagic);
…略
// 各型に応じた名前を返す
void showMagicName(final Magic magic){
final String name = magic.name();
}
…略
}
enumとmapに関して
enum、mapあたりはjavaを使用したことがないため、イメージが湧きづらかった。
mapはphpの連想配列のようなもの。
enumはphpでもあるらしく、一連の定数をグループ化するために使用するものらしい。
mapはキーと値のペアだが、enumは値の羅列、といった感じだろうか。
学び
ストラテジパターンを使用することによって、条件分岐がシンプルになることがわかった。
次のアクション
同様に、フラグ引数ん関してもstrategyパターンが適用できるとのことなので、調べる。