interface 仕様をコードで記述する

とりあえず絵の餅を描いてみるw

interface 上に定義されている関数について、document に仕様を記述し、実装クラスに実装するというのは結構普通に行われるが、その仕様がほぼ純粋に複雑なロジックだった場合、以下のような問題がある。

  • ドキュメント中に書かれた自然言語によるロジック説明が非常にわかりづらい上に曖昧。
  • ドキュメント中のロジックが正しい保証が得られない。
  • 複雑なロジックであればあるほど、ドキュメントとコードが乖離する可能性が高まる。また、乖離したかどうかを確認する機械的な手法が無い。
  • 疑似コード方式でロジックを検討するにしても、疑似コードは実装フェーズの成果物である実装クラス上で行うものなので、要求開発時には行えない。要求開発時に行うためにモジュールの外部インタフェースのドキュメントとして記述するとしても、実装との乖離が無いように保守する必要があり、また、どれだけコストをかけても実装との乖離が無いことを証明する方法がない。*1

上記のような問題を扱う工数をかけるより、kotlin であれば interface 上にソースコードを書いてしまうほうがラクチンな気がする。以下案:

  • 仕様レベルに属する interface のロジック仕様を記述する抽象クラスを作成する。
  • 仕様インタフェースレベルのドキュメントには概要を記述するが、ロジックは一切記述せず、抽象クラスへのリンクを見せるだけにする。*2
  • 抽象クラスは Xxx を implements して XxxBase という命名で統一。(Xxx は仕様レベルに属する interface の名前)
  • 抽象クラスに疑似コードを記述するという作業を全てのモジュールインタフェースに対して行い、その後、仕様レベルのロジックのみ実コードに置き換えていく。*3
  • 仕様レベルで決定する必要が無いロジックは TemplateMethod として実装クラスに丸投げする。*4
  • 切り出したいロジックがある場合は、必要に応じて別関数として切り出す。*5

上記の成果物までを要求開発フェーズの後半に含めることにより、低コストかつ高精度で要求開発の精度が上がるんじゃないだろうか。予想可能な一定の工数を支払う代わりに予想不可能な実装フェーズでの手戻りを減らせるという効果が期待できるかも。特に、開発後期に大人数を投入してリードタイムを削減する場合、設計への手戻りコストが非常に高くつくので、この方法は有効な気がする。

絵に描いた餅おしまいw

*1:そもそも、このような保守は、進捗と品質のトレードオフという概念が存在する組織では成り立たない。品質の全責任を負い、品質以外の一切の責任を持たず、開発部門の全権限を上回る権限を持つ品質管理部門が無い限り無理。

*2:意味的に結合しているので依存しても問題ない。っていうか依存させるべき。

*3:疑似コード作成者はその疑似コードに対する実コードを書いてはいけないというルールがあるといいかもですね。同一の人物やペアが実装することが常態化すると疑似コードの品質維持が難しい気がする。もしくは、レビュー参加者からランダムで実装者を選ぶということにすれば、全レビュー参加者が気を抜けなくなる気がするw

*4:例えばソートする必要がある場合など、ソートアルゴリズムは非機能要件さえ満たせれば何でもいいので仕様記述に含める必要が無い。っていうか含めちゃいけない。

*5:構文的かつ意味的にも重複しているコードの切り出しは必要だが、それ以外のコードの切り出しは細かく切り出し過ぎないように注意する。メソッドは短いほうが良いというのは過去のプラクティスであり、別メソッドに切り出す理由がメソッドの長さだけであるならすべきではない。選択や反復のブロックも、目視するのに困難なレベルの複雑さ以外の時は切り出すべきではない。