論理関係と制約関係(ロジックとアーキテクチャ)の境界を設計する
さて、ここまでの説明で「なるほど、ここで制約と言ってるものは禁止のことか」と思われたかもしれません。その理解は間違ってはいないのですが、「禁止」と呼ばずに「制約」と表現した方が相応しい理由もあるのです。
制約にはいくつか種類がありますので、まずは一番簡単でわかりやすいOne制約を説明します。これは例えば、ラジオボタンやプルダウンメニューが対応します。
複数の選択肢の中の1つしか選べない(必ず1つを選ばせる)制約です。これは2つ以上選択することを禁止していますが、ユーザの誤入力を防いで正しく入力できるようにガイドしてあげていると解釈すると、「禁止」という表現は相応しくなくなります。
さて、言葉の選び方についてはそれぐらいにして、いずれにしろこの制約の機構が入っていれば、論理演算処理では、もうそれ以外のケースがないことを前提とした単純化した設計で済ませることができます。選択肢が1つも選ばれていないケースや、複数選択されてしまっているケース、思いがけないほかの値が入ってくることなどを想定した処理を考える必要がなくなります。
逆に、念のため複数選択されている際にエラーを出すコードを書いたとすると、そのパスを通るテストが難しくなります。UI部と論理処理プログラムを結合したテストの中ではこのようなパスを通すことは困難になるので、そうしたカバレッジ戦略とも整合するように制約と論理処理の役割分担の方針を明確に決めておく必要があります。
もちろんリスクの高いところについては2層防御も必要ですが、どこもかしこも2層防御にするのはコードを複雑化させ、テストを難しくすることにつながり、必ずしも品質向上に有効な方法とは言えません。戦略的に必要な場所を選ぶべきです。こういった制約関係と論理関係を整理して境界を引く際に、原因結果グラフを描くのは最適な方法です。
次にMASK制約(隠蔽制約)関係について説明します。名前がわかりにくいかもしれませんが、よく見るものです。
上の画面は保険の申込サイトを模した画面ですが、「過去5年の入院歴がなし」の場合はそれ以上何も聞かれませんが、これが「あり」だと「退院後経過期間」を聞かれます。就業状態の選択によっても表示される項目が変わります。
ほかにもショッピングサイトの決済の場面で、支払い方法にクレジットカードを選んだ際にだけクレジットカード番号の入力欄が出てきたり、選択肢のどれを選んだかで画面ごと隠され、次の遷移先の画面が異なったりする場合もあります。
こうした制約関係を定義できるのがMASK制約です。触れないように隠蔽してしまうのでMASK制約と名付けられているわけですが、不必要だから間違えないために表示しないようにしているわけで、親切な設計でもあるわけです。
MASK制約とは以下のような制約関係であると解釈しておくとよいでしょう。
MASK制約(隠蔽制約)関係:「A -Mask→ B」は、「Aが真(T)ならば、Bは意味を持たない(それゆえ決してBを操作したり、参照してはならない)。」
上図のようにグレーアウトされるケースもあります。このとき注意すべきなのは、触ることに意味がない場合はMASK制約と解釈するのがよいですが、選択肢や値が決まってしまうのでユーザーが触れられなくしているケースもあります。その場合はMASK制約ではなく論理関係の帰結となるように定義するのがよいので、よく見極めることが肝要です。
※この図の場合、100%がグレーアウトされている意味が「100%に固定されて変えられない」ということなのであれば「拡大縮小指定は100%」だけが真となるような論理表現を選ぶべきです。しかし、選択されているラジオボタンは、複数ページを1枚に割り付けるための指定のようなので、縮小拡大は別の「合わせる」ロジックで計算されるという意味です。つまりこの場合は、グレーアウトは値を固定する意味ではなく、無効だということになるので、MASK制約扱いにするべき、ということになります。
MASK制約(隠蔽制約)は、その名前からわかるように、隠蔽するための制約ということとなりますが、それは誰に対して、何のために隠蔽したいのかを意識しておいたほうがよいです。
次に示すように、主に2つの目的が混在していることが多いと思います。
- システム(あるいはその開発者)がユーザに対し、意味のない操作や入力を行うことを防いだり、誤解を招いたりすることがないようにMaskする。
- 開発者がシステムに対し、意味のない操作や入力が行われることを防いで、不必要にシステムの状態を複雑化させないためにMaskする。
ありがちな事態は、第一義的に前者の目的でMaskされるので、後者の目的としては無意識に、また不徹底に行われることになります。ほかのすべての制約の場合も同じですが、制約に任せたことは徹底して制約として、論理処理をすると決めたことは徹底して論理処理で担保することが肝要です。相手側がやっているはずという思い込みがバグを招いていることもよくあるからです。
