2010年2月13日土曜日

製品指向とフィーチャー指向の可変性実現(1)

前回の最後にプロダクトラインにおける戦略について触れましたが,それを論じる前に,プログラムコードなどの開発成果物で可変性を実現する2つの流儀,製品指向フィーチャー指向を紹介します.


なお,この製品指向,フィーチャー指向という分類の呼び方は,僕独自の見解であって,文献などで裏をとっていません.類似のことを主張している文献は,いかにもありそうなので,もしご存じならコメントいただくと助かります.

可変性を実現するにはさまざまな方法があります.数々の技法を紹介するのは,また別の機会ということで,最も基本的な C 言語のマクロ(#ifdef)を使った方法を見てみましょう.


よくある定義のしかたは,開発する製品に対応して可変性を記述する方法です.この流儀を製品指向と呼びましょう.

#ifdef PRODUCT_A 
 /* 製品 A 向けのプログラムコード */
#endif /* PRODUCT_A*/
なお,「製品 A 向けのプログラムコード」とコメントされている部分には,実際には製品 A だけに実装するプログラムコードを記述します.

C 言語のコンパイラーは,#ifdef の直後に指定されているマクロが定義されているときに #ifdef から #endif までのコードを含めてコンパイルし,そうでないときには含めずにコンパイルします.したがって,製品 A をビルドするときには,コンパイルスイッチでマクロ PRODUCT_A を定義します.そうすると製品 A 向けのプログラムコードを含むソフトウェアが生成されます.

この方法の問題点は,製品の数を増やすときに,プログラムコードを改変する必要があることです.たとえば新たな製品 B を作るとします.そのとき上記の製品 A 向けのプログラムコードを製品 B にも使うとしましょう.この場合,次のようにプログラムコードを改変する必要があります.
#if defined(PRODUCT_A) \  
  || defined(PRODUCT_B) 
 /* 製品 A・B 向けのプログラムコード */
#endif /* PRODUCT_A, PRODUCT_B*/
#if defined(PRODUCT_A) は  #ifdef PRODUCT_A と同じ意味です.ただし, defined を使うと複数の条件を扱うことができます.また,バックスラッシュ(\) は改行があってもマクロが続くという意味で,縦棒ふたつ(||)は「または」という意味です.したがって,この例では,PRODUCT_A または PRODUCT_B が定義されていた場合に #if から #endif までのプログラムコードを含めるという意味になります.

まとめると,製品指向で可変性を記述した場合,製品に対応したコードを生成するときには製品名のマクロを定義すればいいので楽ですが,そのかわり製品を追加するたびにプログラムコードを改変する必要があります.



追記: あとで明かしますが,製品指向は可変性の表現としては悪い例です.このようなコードをあとで説明するフィーチャー指向に改めていく必要があります.

つづく