Warcraft3でデザインパターン: Observer
[ Java ]
第三回目。今回は Observer。Footman がダメージを受けるたびに Paladin がそれを観察し、残り HP が少なくなったら Holy Light で回復させるという流れを Observer パターンで実現してみる。
Observer パターンで言うところの Observer としてインターフェース Hero を記述。Hero は Unit がダメージを受けると notify によってそれを知る。
package observer;
public interface Hero {
public abstract void notify(Unit s);
}
一方、観察される側(Subject)として Unit クラス。(抽象クラス) 状態変化を知らせる相手をプールに登録/削除するメソッドとして addHero(), deleteHero() を用意する。加えて、サブクラスが使用する notifyHeros() を実装する。notifyHeros() の中では Hero#notify() を使用して、Hero に状態変化を知らせる。
package observer;
import java.util.*;
/* Subject */
abstract public class Unit {
private Vector heros = new Vector();
public void addHero(Hero h) {
heros.add(h);
}
public void deleteHero(Hero h) {
heros.remove(h);
}
public void notifyHeros() {
Iterator it = heros.iterator();
while (it.hasNext()) {
Hero h = (Hero) it.next();
h.notify(this);
}
}
public abstract void recoverHitPoint(int hp);
public abstract int getHitPoint();
public abstract void damage(int dam);
}
Hero インターフェースを実装するクラス、ConcreteObserver として Paladin クラス。Paladin は Unit から状態変化の知らせ(notify())があると、HPを調べて少なかったら Holy Light で HP を回復させる。
package observer;
/* Concrete Observer */
public class Paladin implements Hero {
public void notify(Unit u) {
// HPが100を切ったらHoly Lightで回復させよう
if (u.getHitPoint() < 100) {
holyLight(u);
}
}
public void holyLight(Unit u) {
System.out.println("Paladin: Holy Light!");
u.recoverHitPoint(300);
}
}
Unit クラスの実装クラス、ConcreteSubject として Footman。Footman はダメージを受けるたびに、自身が知っている Hero に対してそれを通知する。
package observer;
public class Footman extends Unit {
private int hp = 420;
public int getHitPoint() {
return hp;
}
public void damage(int dam) {
hp -= dam;
System.out.println("Footman: 被" + dam + "ダメージ(" + hp + ")");
// ダメージを受けたらHeroに知らせる
notifyHeros();
}
// HP回復
public void recoverHitPoint(int hp) {
this.hp += hp;
System.out.println("Footman: HP回復(" + this.hp + ")");
}
}
以上で役者は揃ったので、クライアントとして Main クラスを用意する。Footman と Paladin のインスタンスを生成して、Footman に適当にダメージを与えてみる。
package observer;
public class Main {
public static void main(String[] args) {
Hero h = new Paladin();
Unit u = new Footman();
u.addHero(h);
u.damage(400);
u.damage(100);
u.damage(50);
u.damage(20);
u.damage(100);
}
}
実行結果は以下。Footman の状態変化に合わせて適時 Paladin が Holy Light で HP を回復させている。
Footman: 被400ダメージ(20)
Paladin: Holy Light!
Footman: HP回復(320)
Footman: 被100ダメージ(220)
Footman: 被50ダメージ(170)
Footman: 被20ダメージ(150)
Footman: 被100ダメージ(50)
Paladin: Holy Light!
Footman: HP回復(350)
Posted by naoya at May 7, 2003 01:00 AM
| トラックバック (0)