ロジックは分割する
スパゲッティコードにしないため、ロジックは適切に関数へ分割しましょう。
分割する際には仕様書の作成でリストアップしたロジックを利用します。例えば「データをデータベースから取得する」という処理ロジックがあるのであれば、以下のようにしてデータベースから取得する部分は別関数として書くとわかりやすくなります。
let data = fetchFromDatabase();
その場合、仕様書に日本語で書いたロジックをそのまま英語表記にすると、関数名としてわかりやすいでしょう。
その場合でも、たとえば「データをデータベースから重複を除きながら取得しキーでソートする」というロジックの場合は悩ましいところですが、実装については 3 週類考えられます。
1 つ目は愚直に書いてみます。ちょっと関数名が長すぎて分かりづらいですね。
let data = fetchFromDatabaseWithUniqAndSortedWithKey();
他にはオプションを渡す方法も考えられます。
let options = {uniq: true, sortedKey: “user”};
let data = fetchFromDatabase(options);
また、JavaScript に詳しい人ならメソッドチェーンを使いたくなるかも知れません。
let data = fetchFromDatabase()
.filter((d, index) => data.indexOf(d) == index)
.sort((a, b) => a.user > b.user ? -1 : 1);
一見すると内容まで確認できる 3 つ目の処理がわかりやすいようにも見えますが、処理している意図がわかりやすい 2 つ目のほうが後からバグを発見しやすい場合が多いです。
オブジェクト指向を意識する
最近のプログラム言語には、オブジェクト指向的なアプローチが準備されています。
オブジェクト指向を理解するだけで、プログラムはわかりやすくなるしミスが少なくなります。
(とは言え、単語としてのオブジェクト指向という言葉は非常に幅広くなってしまってますので、概要を理解して意識するだけでも問題ありません)
例えば、以下のような CSV ファイルのデータを利用しようとしたときのことを考えてみます。
id | name | |
---|---|---|
1234 | hoge | hoge@example.com |
CSV ファイルのデータであれば配列を利用する場合が多いので、名前を取得しようとしたら以下のようになるでしょう。
let name = data[1]; // 列番号でアクセスする必要がある
これがオブジェクトを利用することで、以下のように記述できるようできます(それなりに準備は必要)。
let name = data.name; // プロパティを準備しておくと「name」を参照していることがはっきりする
また、これを CSV ファイルに書き出す場合、以下のように記述できるようにもできます(それなりに準備は必要)。
data.writeTo(filename); // オブジェクトにメソッドを追加出来るので引数が少なくなる
オブジェクトを作成するためのクラスを準備する必要はありますが、クラスさえ作成しておけばメインロジックは非常にスッキリした形にできます。
クラスは再利用できます。ということは、担当者分けして実装することも出来ますし、何度も利用されたクラスであれば十分にテストされていることも期待できます。
クラスごとに仕様書が作成され、それぞれで十分なテストが行われていれば、利用者にとってはクラスの内部処理が理解できなくとも安心して利用できるようになるというメリットがあります。
個人的に、オブジェクト指向で考えるときは「オブジェクトの気持ちになってどう指示を出されると動きやすいか」ということを考えると良いです。
指示する側から考えると 1 回の命令でいろいろまとめて指示出したくなりますが、できるだけ簡潔な指示と必要最低限のオプションを与えると良いオブジェクトになります。
オブジェクト指向を語るときは「継承」や「ポリモーフィズム」など難しい単語がたくさん出てきます。
ですが、以下の内容だけ覚えておけばとりあえずは問題ありません。
- 「クラス という設計図」を元に
- 「インスタンス という実体」を複数作ることができ
- 「プロパティ と呼ばれる個性」を持っているそれぞれに
- 「メソッド と呼ばれる命令」を出すことが出来る