Visitorパターンとは、オブジェクトの構造を変更せずに新しい操作を追加できるデザインパターンだ。これにより、オブジェクトのデータ構造に対して、異なる操作を簡単に追加できる。
たとえば、ゲームのキャラクターに異なるスキルを追加したり、装備の種類を増やしたりする場合に使える。
では、サンプルコードを一緒に見ていこう。
たとえば、動物園の動物に対して、いろんな新しい行動を追加してみるという例で説明していくよ。
まず、動物園にいる動物たちを表現するクラスを作る。これらの動物に対して新しい行動(たとえば、「餌をあげる」「健康チェックをする」)を追加していくよ。
// 動物の基本クラス
class Animal {
accept(visitor) {
// Visitorが訪問したときに、具体的な行動を渡す
visitor.visit(this);
}
}
// ライオンとゾウのクラスを作成
class Lion extends Animal {
roar() {
console.log("ライオンが吠えました!");
}
}
class Elephant extends Animal {
trumpet() {
console.log("ゾウが鳴きました!");
}
}
次に、動物に対して操作を行うVisitorを作成する。Visitorは、特定の動物に新しい行動を与える役割を持っているよ。
// 動物に新しい行動をさせるためのVisitor
class FeedVisitor {
visit(animal) {
if (animal instanceof Lion) {
console.log("ライオンに肉をあげました!");
} else if (animal instanceof Elephant) {
console.log("ゾウに草をあげました!");
}
}
}
class HealthCheckVisitor {
visit(animal) {
if (animal instanceof Lion) {
console.log("ライオンの健康チェックをしました!");
} else if (animal instanceof Elephant) {
console.log("ゾウの健康チェックをしました!");
}
}
}
動物に対して、Visitorを使って新しい行動を追加していこう。Visitorパターンを使うことで、動物のクラス自体を変更せずに、新しい行動をどんどん追加できるんだ。
// 動物を作成
const lion = new Lion();
const elephant = new Elephant();
// Visitorを作成
const feeder = new FeedVisitor();
const healthChecker = new HealthCheckVisitor();
// ライオンに餌をあげる
lion.accept(feeder); // 結果: ライオンに肉をあげました!
// ゾウに餌をあげる
elephant.accept(feeder); // 結果: ゾウに草をあげました!
// ライオンに健康チェックをする
lion.accept(healthChecker); // 結果: ライオンの健康チェックをしました!
// ゾウに健康チェックをする
elephant.accept(healthChecker); // 結果: ゾウの健康チェックをしました!
これでVisitorパターンの解説は終わりだ。
このパターンを使うと、オブジェクトの構造に手を加えずに新しい操作を追加できるため、柔軟性の高いシステム設計ができる。