分かりやすいコードってどういう事だろう。構造の観点からつらつらと。

分かりやすいコードとはどういう事だろう。人に「伝わる」コードってどういうことだろう。それはコードを書く人にとって、常に頭の中で考えておいた方がいい、職人気質の原則なのだと思う。(ソフトウェア職人気質やアプレンティスシップ・パターンにそういう原則があったかどうかは定かではありませんが。)で、今日はその事についてつらつらと述べよう。

僕はオブジェクト指向を学び始めた頃、オブジェクト指向を使うと分かりにくいコードができてしまう、と感じていた。読んでいた本は結城浩さんの「Javaで学ぶデザインパターン入門」とか。その時はまだ学生で、ソフトウェア開発というのがどういうことなのか、よくわかっていなかった。*1
同じ時期によくあるCGIの掲示板をアルバイトで構築していた。そのCGIはPerlで書いていた。使っていたPerlのバージョンは、確か5.0系だったと思う。Perlオブジェクト指向プログラミングをする是非はこの際横に置いておこう。;-)

掲示板のような分かりやすいソフトウェアをオブジェクト指向で実装すると、そもそものコードの量が増えるので読まなければいけないコードの箇所が増え、制御構造がより絡み合っているように見えた。だから、関数だけで実装すれば簡単な少数のファイルで組めると思っていた自分には、「オブジェクト指向ってなんかビミョーだな」と思えていた。

その後IT業界に就職した。就職した先は大手ではない中小のSIer。どちらかというと小さい方だが、下請けSIのみではなく、一次受けの仕事もそれなりにあった。実際に使われる業務システムは掲示板よりは複雑で、画面数もそれなりに多く、一つ一つの機能ごとに入力チェックの機構を作るのは骨が折れると思えた。ちょうどその頃、DI+AOPフレームワークがはやり始めた頃で、自分のいたプロジェクトではSpringFrameworkの上に構築されていた。SpringFrameworkの中はどんな風になっているか、興味があったので覗いてみると、そこには「デザインパターン入門」で学んだTemplateMethodパターンやFactoryパターンががっつり使われていた。また、一つ一つのクラスの責務も分かりやすく、いわゆる「単一責務の原則」がどう実現されるべきか、そのお手本として学べたソースコードだった。クラスの名前も命名規則が用意されているなど、配慮されていて理解しやすかった。

ただ、自分たちが実装していたWebアプリケーションは、画面ID(6桁)+Actionみたいな残念な命名規則だった。上司曰く、画面IDで大体の機能が分かるからこうしている、みたいな事を聞いた気がするが、一回爆発すると良いと思った。画面IDと機能一覧のマッピング表をExcelで作っておくなんて玄人思考は素人に全く優しくない。最初IMEが玄人を"苦労と"ってIMEが変換してくれたが、間違ってないと思う。空気を読む素敵なIMEだ;-)

そのWebアプリケーションはプレゼンテーション層、ビジネスロジック層、DAO層のクラスのレイヤ分けはされていた。けど、なんのためにレイヤ分けしているのか、訳が分かっていた開発者は、自分の周りにいたのだろうか。なんか、「そうするのが今時の開発」というメディアに踊らされていた感がある。結局開発者が行うテストはブラウザからぽちぽちボタンを押してはキャプチャをとるあれである。今なら分かる事の一つは、ビジネスロジック層のテストコードを書くために、DAO層を差し替えるStubを使えば、それなりに自動テストできるんじゃなかろうか、ということか。一回ブラウザから送られてくるリクエストパラメータをファイルに保存しておき、プレゼンテーション層に渡ってくるであろう入力値として使えばそこも自動化できるみたいな事を妄想していた時期もあったけど、今はSeleniumとかブラウザ上の操作を自動化できるライブラリがあるのでいい。

おっとっと。話が脱線してきたぞ。要するに、中小SIerにいた頃は画面数はそれなりに多く、フレームワークの中でオブジェクト指向は活用してきたけど、アプリケーションの中は名ばかりのオブジェクト指向で、活用できてなかったと思うんだ。そこには「オブジェクト指向を使う」目的なんてなかった。なんていうか、自己満足のためのオブジェクト指向みたいな。開発者が楽になってないオブジェクト指向とも言えるかもしれない。ともかく、これも当時は「びみょー」に感じていた。

ただ、担当者毎に画面を実装していたので、制御構造がぐちゃぐちゃにはならない、という利点はあったけど:-P

ソフトウェアの設計原則に「関心毎の分離」がある。一つ一つの関心毎に実装があるので、その実装が何を実装したくて作られたのか、分かりやすい。そういう意味で、レイヤ分けをしておく事に意味はあったのかもしれない。ただ、何も考えずにレイヤだけ分けたので、ビジネスロジック層が持つ関心毎が次第に増え、意味もなく分厚くなっていたけど。

そろそろまとめ。このエントリの中で言いたかったのは、うまく「関心毎の分離」を行い、「単一責務」にクラスを分離できれば、分かりやすい構造がうまれるんじゃないか、と言う事。それがコードの理解しやすさにつながるんじゃないか、と今は思っている。冒頭の掲示板の例は、「掲示板」という機能の実装に必要な関心毎がそれほど多くないので、逆に分離する事で、構造が持つ複雑さの分、難しくなったのではないか、ということ。けれど、業務システムのような関心毎が多いソフトウェアであれば最初から分離しておいた方が分かりやすいのではないか。そのあたりのバランスの取り方は経験に寄るものが大きいが、うまく活用していこう。

*1:ただ通っていた高専の教科書にはWFは2度流すプロセスときっちり書かれてた。良書だったと思う。SICPとかはやってないけど、ヘネパタ本とか読んでた。今はパタヘネ本ですか。