自分はフレームワークを用いてWebアプリを書くことが多いのですが、その上で可能限り「良いコード」を書くように心がけています。
ただ、この「良いコード」というのがかなりの曲者で、プログラミングにおいてのイディオム的なことからオブジェクト指向の話、デザインパターンやプログラミング言語においてのベストプラクティス、使用しているフレームワークのベストプラクティス、さらに広げるとドメイン駆動設計の話までかなり広い範囲が含まれてしまいます。
チームによっての技術レベルや目標としているものはもちろん違うので、基本的には現場現場で話し合って自分達の目指す「良いコード」を定義することが重要になるでしょう。
今回はMCVフレームワークを使ってWebアプリケーションを良いコードで書く上で、どの現場でも理解できて、かつ実践できるであろう私の頭にある「良いコードを書く」ための基本的な方針をまとめてみました。
まとめる上で、出来る限りオブジェクト指向やエンタープライズアーキテクチャなどの用語を使わないように意識しています。
特に真新しいことはなにもなく、当たり前になっているとは思いますが、自分の頭の中を吐き出すためにこのブログを使おうかと。
基本的な方針
1.やっていることが違うコードは分離して名前をつける
管理画面などをMVCフレームワークで開発をしていてたまーにあるのが、おなじURLにPOSTされていても送信されてくるデータによって新規作成になったり、更新になったり、または違うテーブルのデータを更新する処理にかわったりすることです。これは管理画面を作る際に関連のある2つのテーブルのデータをユーザビリティのために一つの画面で更新できるようにした場合に発生します。
この時に愚直にコントローラー内の一つのアクションにすべての処理を書いていくと、コードが長くなりますし不用意に別の役割をしているコードに依存した処理を書いてしまいバグの温床になることがあります。
出来るだけ違うことをおこなうアクションは別にする。 もしUX上別に出来ない事がある場合はおなじアクションを叩くにしても内部上では別のメソッドを分離して、そのメソッドに処理を行わせるようにしています。
もちろんこれはコントローラーだけではなく、その他のプログラムにおいても同じです。
分離したメソッド名を適切な名前にすると、その名前をみるだけで何をしているのかわかるので可読性も上がります。
2. どこに責任を持たせるのかを決める
例えば商品を表現するDBのテーブルproductsがあり、各商品の識別子(ID)は企業名を表すアルファベット二文字(PKやITなど)とインクリメンタルの数値の8桁でないといけないというルールがあるとする。
そのようなルールがあったときに、商品の作成処理をおこなうControllerで毎回ID作成のためのロジックを書くのはコードの重複が増える上にプログラマーがルールを常に覚えていないといけないため問題です。
その問題を避けるため、商品の識別子を作成するためのメソッドを定義し、商品識別子の作成ロジックの責任はこのメソッドのみに持たせます。
責任を持たせるメソッドを定義することによりコードの重複が減り、かつビジネス上のルールをコードで表現することで可読性が上がります。
3. Web以外のインターフェースがあることを意識する
Webアプリケーション開発においてMVCフレームワークを使って開発をしているとき、注意をせずに開発をすると重要なビジネスロジックがコントローラー側に漏れていく事が多くあります。しかしControllerはWebのRequestとResponseが交わる場所になるので、ここにビジネスロジックを書くとWebのRequestとResponseに依存したプログラムになってしまいがちです。
そんなときに困るのが、同じような機能を提供する別の画面を作ったり、WebのUIではなくWebAPIを作ったり、またはコマンドラインのタスクを作ったりなど別のインターフェースから同一の機能を提供しようとしたときに、ロジックを抽出するのが難しくなってしまいます。
そのため、重要なビジネスロジックを書くときには常に今のUIとは別のUI・インターフェースから使われるときのことも意識し、Controllerから分離してコードを書きます。
4. 小さなプログラムを組み合わせて大きなプログラムを書く
大きなプロダクト一塊にして書くよりも小さなプログラムを作って細かく分割し、それを組み合わせて大きな機能を作ります。
そうすることで依存性も低く再利用性も高い小さいなコード群がたくさん生まれ、別の機能を作るときにそれらのコードを使ってより早く開発することができます。
おわりに
もちろん上記以外にも考えることは多いのですが、私が特に意識しているのがこの4つです。
こういうのを「単一責任の法則」的な法則名で意思疎通できると、話は早いんだろうなー。