TemplateMethodパターンはスーパークラス(ベースクラス)でロジックの概要設計あるいは共通部分を実装し、詳細ロジックあるいは非共通部分をサブクラスで提供するパターンです。
大げさに言うとスーパークラスでプチフレームワークを実装するようなイメージです。
TemplateMethodパターンのメリットは
- サブクラスで共通なロジックをスーパークラスで共通化できる。
- ロジックの骨組みが明確になっている為、コードが把握し安い且つメンテナンスコストが軽減されやすい。
それではクラス図をご覧ください。
ちょっとメソッドとか多いですけど簡単な継承関係です。
このクラス図で重要なのは
で、Characterクラスのmove()がテンプレートメソッドに相当します。- move()
- canMove()
- canMoveEach()
- moveEach()
次にソースを見てみましょう、用意するのは次のファイルです今回からクラスのcppファイルを用意しない方が見やすいかなと思って.hだけ用意しました。
- main.cpp
- Character.h
- Monster.h
Character.h
#ifndef _CHARACTER_H_ #define _CHARACTER_H_ #includemove()のなかでmove可能ならばmoveするという大まかなロジックを実装しています。class Character { //---------------------------------- // field //---------------------------------- private: int HP; int MP; //---------------------------------- // property //---------------------------------- public: const int getHP() { return this->HP; } Character& setHP(const int _hp) { this->HP = _hp; return *this; } const int getMP() { return this->MP; } Character& setMP(const int _mp) { this->MP = _mp; return *this; } //---------------------------------- // method //---------------------------------- public: Character() : HP(100), MP(100) { // do nothing... } virtual ~Character() { // do nothing... } void move() { // テンプレートメソッド // move可能判定 if (this->canMove()) { // move this->moveEach(); } } private: virtual const bool canMove() { // HPが0ならmove不可 if (this->getHP() <= 0) { return false; } return this->canMoveEach(); } protected: virtual const bool canMoveEach() = 0; virtual void moveEach() = 0; }; #endif
Monster.h
#ifndef _MONSTER_H_ #define _MONSTER_H_ #include "Character.h" class Monster : public Character { //---------------------------------- // method //---------------------------------- protected: virtual ~Monster() { // do nothing... } virtual const bool canMoveEach() { printf("canMoveEach\n"); return true; } virtual void moveEach() { printf("moveEach\n"); } }; #endifMonster独自のcanMove()、move()をcanMoveEach()、moveEach()で実装しています。Eachっていう名前の付け方は一般的ではない気がします。
main.cpp
#include#include "Monster.h" void main(void) { // Monster生成 Character* character = new Monster(); // move character->move(); // HPに0を設定 character->setHP(0); // move character->move(); delete character; printf("hit any key...\n"); while(getchar() == EOF) {} }
0 件のコメント:
コメントを投稿