見やすく管理しやすいコーディングのコツ
プログラムが小さい場合はあまり問題になりませんが、プログラムが複雑になって大きくなってくると、コーディングのやり方によっては、管理が大変になる場合が多くなります。この記事では、「見やすく」「管理しやすい」コーディングのコツを紹介します。
誰がプログラムを読むか?
最初にプログラムを書いた人以外が、プログラムを見る(読む)ことは、現実的にかなりあります。 一人で開発を行っていても、依頼されてプログラムの開発を行う場合、納品後の管理は依頼者側で行う場合が多くなります。また、会社などでは、最初にプログラムを書いた人が退職したり、別の仕事に就いたりして、その後の管理は別の人が行う場合もたくさんあります。
また、プログラムを書いた本人でも、時間が経つと細かい部分は忘れてしまう場合が多く、開発してしばらくして何かの問題が出て、プログラムのコードを見直す場合には意外に時間がかかってしまうものです。
こうした事態に備えるため、業務でプログラムを開発する場合はドキュメント(設計仕様書)を作成するのが普通です。 しかし、ドキュメントがあっても、プログラムのソースコードはいずれにしても読む必要があります。 つまり、ソースコードが見やすく、管理しやすいよう書いてあるかどうかで、そうした管理のために費やす時間は大きく変わってきます。
ハードコーディングの問題
管理が面倒なプログラムに「ハードコーディング」が多いプログラムがあります。 「ハードコーディング」とは、プログラムの中に「具体的な値」を直接書く書き方です。
例えば、最近の投稿で紹介している、Vue と Firebase による、ブログサービスの例を考えてみると、Firebase のストレージに投稿の原稿となるファイルを保存しています。この保存先のフォルダ(bucket)の名前が仮に「blog」というフォルダ(bucket)に保存する場合には、この値を指定して、ファイルを Firebase ストレージに保存する必要があります。
試しにプログラムを書いて基本的な動作を確認するだけの場合には、直接「"blog"」のように、フォルダの名前を書いても余り大きな問題にはなりません。こうした場合には、確認が終わればそのプログラムを使うことは余りなく、その場限りなので大きな問題にはなりません。
const fileRef = ref(storage, "blog" + "/" + file.name);
のように書けば、必要な機能は実現可能です。
ところが、この「値」を使うのは、複数の場所になる場合が殆どです。
* ファイルを Firebase のストレージにアップロードする場合
* Firebase ストレージのフォルダ(buckt)ないのファイルの一覧を取得する場合
const listRef = ref(storage, "blog");
listAll(listRef).then((res) => {
....
});
のように別の場所でも使います。この例では、2箇所に「"blog"」を書くことになりますが、場合によっては、さらに他の場所でもこのフォルダ(buckt)の名前を使う必要があります。
そのような場合に、幾つか問題が起こる可能性があります。
* 「blog」の入力を間違える(例えば「vlog」)
* フォルダの名前を変えたい
などは良く起きる例です。
複数の場所でその度に「値」を打ち込んでいると、タイプミスをして一つだけ値が本来とは違うものになってしまうことがあります。その場合には、プログラムは正常には動作しない場合が多くなります。
また、フォルダの名前を変えたい場合には、その値を使っている場所全てを書き換える必要があります。 プログラムの開発中ならば、どこで使っているかもわかっているので修正もある程度可能ですが、使っている場所が多かったり、時間が経っている場合には、一部の変更がされない場合も考えられます。
そうしたことを考えると、こうしたケースでは、
const FOLDER = "blog";
const fileRef = ref(storage, FOLDER + "/" + file.name);
....
const listRef = ref(storage, FOLDER);
listAll(listRef).then((res) => {
....
});
のようにしておけば、1箇所を変更すれば全ての変更がされるので、ミスを減らすことも可能です。また、どこでその値を使っているかを覚えておく必要もなくなります。
数字に意味がある場合
別のハードコーディングの問題は、数値で状態を表すようなプログラムを書く場合です。
例として、
* 0: 小学生
* 1: 中学生
* 2: 高校生
* 3: 大学生
それ以外
のように分類したとします。
switch (group) {
case 0:
functionForElementarly();
break;
case 1:
functionForMiddlSchool();
break;
case 2:
functionForHighSchool();
break;
case 3:
functionForCollege();
break;
default:
functionForOther();
break;
}
それぞれのグループで別の処理を呼び出すというプログラムです。 呼び出している関数を見るとある程度は、どんな意味かは想像可能ですが、分かりづらくなってしまいます。
このような場合も、定数に名前をつけて、プログラムを書くと読みやすいプログラムになります。
const ELEMENTARY = 0;
const MIDDLE_SCHOOL = 1;
const HIGH_SCHOOL =2;
const COLLEGE = 3;
....
switch(group) {
case ELEMENTALY:
functionForElementarly();
break;
case MIDDLE_SCHOOL:
functionForMiddlSchool();
break;
case HIGH_SCHOOL:
functionForHighSchool();
break;
case COLLEGE:
functionForCollege();
break;
default:
functionForOther();
break;
}
もちろん、コメントを入れて書けば同じような効果がかりますが、上のように書けばコメントを入れなくても、読みやすいプログラムになります。
複数のファイルで同じ値を使う場合
これまで紹介したように、ハードコーディングをしないでプログラムを書くとプログラムが見やすくなります。これが、同じファイルの場合には、ファイルの最初にこうした定数をまとめて書いておけば良いことになります。
ところが、同じ値を複数のファイルで使う場合には、ファイルごとに毎回こうした定数を書くのは、これも複数の場所で定数を宣言する事になるので間違いや変更が大変になってしまいます。
そのような場合は、一つのファイルに定数の宣言をまとめてしまうと使いやすくなります。
// constants.js
export const ELEMENTARY = 0;
export const MIDDLE_SCHOOL = 1;
export const HIGH_SCHOOL = 2;
export const COLLEGE = 3;
import * as CONSTANT from "./constants.js";
// sample.js
switch (group) {
case CONSTANT.ELEMENTALY:
functionForElementarly();
break;
case CONSTANT.MIDDLE_SCHOOL:
functionForMiddlSchool();
break;
case CONSTANT.HIGH_SCHOOL:
functionForHighSchool();
break;
case CONSTANT.COLLEGE:
functionForCollege();
break;
default:
functionForOther();
break;
}
このようにすることで、複数の場所で同じ値を使う場合には、1箇所でまとめて定数を宣言してしまえば、変更も、間違いも最低限で済みます。
まとめ
この記事では、見やすく管理しやすいプログラムの書き方の例として、特にハードコーディングを避けて Javascript のコードを書く例を紹介しました。他のプログラミング言語でも、似たような手法が利用できます。
プログラミングを書くスタイルは、書く人や組織(会社)によっても違います。 しかし、ハードコーディングを避けることで、プログラムの変更・修正がシンプルになりますし、プログラムの読みやすさも大きく向上します。
小さなプログラムでは、効果は少なくなりますが、このようなプログラムの書き方を習慣にすることで、バグが少なく見やすいプログラミングが可能になります。
余り、本などでは紹介されていませんが、プログラムを書く上では大切なことの一つです!