フラグを使わない実装パターンとか2011/11/29久しぶりの実装ネタ。パターンとかいう程の話ではないんだけれども。型のフラグを多用しているプログラムはへたっぴだと言われています。値(真偽値)を持つ型のこと。ここで,ロジック上真偽値として使われていれば,実装時の型は整数型でもなんでも構いません。具体的には次のような関数を作るのは,へたっぴということ。}}こゆ処理の最もよくないところは,呼び出し側で何を設定しているか分からないところです。何を表しているのか分からない。実装やマニュアルを読まなきゃいけません。some_func(true);理想は,呼び出し側でどのような意味の値を渡しているのかが分かるといい。次のようになっていれば,おおむね何をやっているかが分かります。true;some_func(good);しかし,これもあまり上手くない。型の値に過ぎないからです。しての役割と機能があるはずなんだけれども,こうした意味はまったく引数として盛り込まれません。実装で,if-文の分岐があるのもよくありません。値をひとつしか渡してないけれども,2つ渡したら4パターン,3つ渡したら8パターンといった具合に,考慮すべき状態が増えてしまいます。状態が増えるに従って,フラグの数を増やしていくと,場合の数が指数関数的に増加することになります。こゆ問題を解決する方法はいくつかあるけれども,一番お手軽な方法は,if-文の中身を他のクラスなり関数(ポインタ)なりに委譲して,状態に対する振る舞いごとパラメタ化してしまうことです。上の例は,次のように書ける。health.do();}こうすれば,呼び出しは次のようになる。if-文もなくなります。some_func(good());ポイントは,状態を「値」から「型」に昇格させた点にあります。型だから,状態に対する振る舞いを定義することができる。ここでは動的に状態を変更している(仮想関数を使って実行時に判断している)けれども,あらかじめ静的に状態が決まっているなら,テンプレートを使ってもいい。応用として,以下のようなサンプルを書いてみました。あるパラメタの定義と設定,それにチェックの処理です。見るプログラムでは,パラメタ定義を動的に作っているものもあるけれど,パラメタ定義はあらかじめ決まっていることが多いから,静的に決定することができます(だからテンプレートを使う)。ここでは,パラメタの属性について,必須パラメタか任意のパラメタかの状態を設定できるようにしてみました。するようにしたために,判断と振る舞いが分かれてしまっているからです。導入すれば,if-文はなくなります。面倒そうに見えるけれど,拡張するときの手間は,単純なフラグを使うよりこちらの方が少ないと思います。