デザインパターンを覚えたい (Factory Method)

Factory Methodパターン

作成のためのメソッドだけフレームワーク側で提供して、実際の作成をサブクラスに任せるというパターン。
Factory、つまり工場なわけですが、工場で製造工程だけは先に決めといて、実際になに作るかは後で決めるみたいなイメージかなぁ。
Factory Methodパターンのいいところは、

  1. オブジェクト作成の処理をフレームワーク側が持つので、作成時の処理を共通化できる
  2. 使う側はFactory経由ですべてのProductを共通の方法で作成でき、Productも共通の方法で使える

といったところですか。うーん、正直言うとあまりうまく利点を理解できてないと思う。Factoryはホントよく名前聞くのでしっかり理解したいですね。

何はともあれ実装。いろいろなオブジェクト指向言語でとか思ってたけど、

  • 使う言語の準備に時間がかかる
  • そもそもパターンに向かない言語を使ってるように感じる
  • 後々確認するときに不便

という理由から、以降は使う言語を絞ってデザインパターンの学習に焦点を当てることにする。
言語はC++, C#, Javaあたりに絞りますか。

気を撮り直して実装。C++で書いてます。
http://dl.dropbox.com/u/7810000/code/design_pattern/factory_method.zip

Javaでいうところのパッケージをどうやって実装するかが問題。Javaだとprotectedにした場合のアクセス範囲にパッケージ内ってのがあるから綺麗にかけるけど。
C++名前空間はアクセス制御には使えなかったばずなので、Friend関数で無理やり実装。例の如くヘッダの依存関係で苦しむ。

コードのポイントは

    Factory* carFactory = new CarFactory();
    Factory* airPlainFactory = new AirPlainFactory();
    Factory* trainFactory = new TrainFactory();

で各プロダクトのFactoryを宣言して、

    productList.push_back(carFactory->create("id_car", "フェラーリ", 10000.00, "red"));
    productList.push_back(airPlainFactory->create("id_airplain", "メビウス1", 30000.00, "yellow"));
    productList.push_back(trainFactory->create("id_train", "京急線", 50000.00, "red"));

    BOOST_FOREACH( Product* product, productList) {
        product->explain();
        product->use();
    }

で共通処理を呼び出しているところ。main関数内ではそれぞれのProductのコンストラクタは明示的には呼んでないし、ループ内もすべて同様の処理。
ビルドと実行は以下のとおり。

$ unzip factory_method.zip
$ cd factory_method
$ omake
$ ./factory_method_test
Car: id[id_car] name[フェラーリ] price[10000] color[red]
ヒャッハー! やっぱりフェラーリは最高だぜ!
AirPlain: id[id_airplain] name[メビウス1] price[30000] color[yellow]
メビウス1 engaged the target.
Train: id[id_train] name[京急線] price[50000] color[red]
京急線, ダァシエリエス!!

ところで、omakeでビルドするとき、一緒にテストも実行するようにするにはどうすんのかね。次はomake叩いたところで実行までされるようにしたい。