09

どこまで薄くできるのか

前回サーバサイドが大分薄いシステムを作っている話を書いたのだけれども、こんなに薄くて大丈夫なのかなとぼんやり考えていた。

考えてみると、今実装している機能はドメインロジックらしきものがとても薄い。ドメインロジックが複雑な場所ではこんな実装にすることは難しいのかもしれない。大概のシステムではドメインモデルをきちんとレイヤ分割やクラスシステムによって保護できるように設計しつつ、WEBシステムとしての構造に組み込んでいくだろう。ドメインロジックが複雑であればあるほどそのロジックを持つクラス周辺が大きな構造になるが、自分が今実装している機能は他の業務に影響したり影響されたりする要素が少なく、ぶっちゃけて言えば業務フローにおいてはスキップしても構わない機能だ。おもに後続業務の効率化のために存在していて、いわゆるクリティカルパスではない。

要するに、業務の関係でよそに配慮したり逆にガードしなければならない部分があまり多くない。

業務システムといっても利用する組織規模によって必要な事項は大分違っていて、大規模になればなるほど業務ドメインごとのデータの完全性が重要になりそうだが、小規模の場合はむしろ人による制御の可能性の方が重要視される場合が多いように思っている。一般的に人によるデータに対する制御可能性を高めようとするとある程度データの完全性は妥協しなくてはならない。順序付けて並べられた業務プロセスを順番に完了させていくのではなく、業務の個別のステップは状態が確定せず同時進行的に進むというようなことを業務フローとして許容できるシステムを要求されることがままある。大規模な組織的利用をするシステムなどでこういった設計を適用してしまうと、適切に情報共有されない部署間の問題などで全体として一貫した対応が取れず、コントロールを失ってしまう可能性がありそうだが、中小規模ならば逆にこのような形態の方が都合がいいという場合もある。

まあ、今回のはそんなに規模が大きくない前提というわけだね。

実装の方に話を戻すけれど、そもそもクライアントサイドでデータ構造を作ってJSON/Ajaxで飛ばすことも割と普通になってきている昨今、クライアントから受け取ったデータを静的型のモデルにマッピングする処理は最低限でいい(フレームワークによるサポートも充実している点も理由としてある)し、今作っているシステムにおいてはデータベースから取り出した結果をサーバサイドで処理する要件もあまりない。データベースから取り出した結果から複雑な処理を行いたい場合、型システムのある世界では型をもった値に変換したくなるのが普通ではあるけれど、そうでもなければSQLの結果を逐一モデル型をつくってそれに変換するというのはオーバーヘッドになるだけで意味があまりない。現状として必要になっているのは、クライアントサイドで利用しやすいように若干の整形処理を行うことくらい。

たとえば、HTTPを型付のシリアライズデータ(OData?)などで転送して、クライアント側ではTypeScriptみたいな言語(TypeScriptが値にたいして型を持てる言語かどうか知らないが)が型付で受け取れるとか、つまりサーバサイドの型をクライアントサイドの型に簡単にマッピングでき、かつその利点を生かせるのならばサーバサイドでも厳密に肩を扱うことに意味が出てくるだろう。

しかし現状それはないので、まあ特別型を使うことにこだわる必要がない。

あとまあ、個人的な経験を振り返って、あるデータ型のオブジェクトから、別の似たような(しかし明確に異なる)型のオブジェクトへひたすら値の転記をやるというコードを過去に何度も書いていて、いい加減(コード上だけでなく実処理として)価値がないよなという認識になっていて、そういった処理を極力排除してみたいという欲求があるというのも、こんな実装にしている理由としてはある。

ただまあ、若干テストについては悩んでいる。

既に述べているとおり、HTTPの入り口からデータベースまでのレイヤがとても薄いシステムになっている。データベースを使用したロジックのテストにおいては、データベース側を抽象化しておいて、モックに差し替えるなんてことをやるのが常套なんだろうけども、サーバサイド側の実装がとても薄いと、あまりそういうものを差し込む場所がない。テスタビリティが低いというのかもしれないが、そのために "SQLを発行して連想配列の配列を吐き出す実装" をモック化したとして意味があるようにも思えない。結局SQLが正しく構成されて発行されるかが重要になっているので、そういう意味では、DBに接続してエンドツーエンドで実行するテストを網羅的に用意した方が、テストとして効果が高い気がする。結局DB依存のクエリなどもあるし、今回の案件は既存システムに対する改修なのでALTERTABLEみたいなデータベース変更もあるため、その辺含めてDBMS様的にも問題ないかチェックしてもらえた方がいい。 つまり、モックを使用したテストにあまり時間をかける価値を感じていない。

自動テストでデータベースに接続してスキーマ作ってなんてやっているととても重いテストになってしまうんだけど、最終的に大掛かりなCIなんかを目指すと結局そこはやりたいし、今回の構成でもっとも効果が高いのはそういうテストだと思っている。 ただまあ、環境が.NETということで全く勝手がわからないのだけど。少し時間が出来たら調べてみようと思う。うまく回りそうならまだブログに挙げることにしよう。