はじめに
今日はコードの書き方の基礎を学習。
「コードは他の人が見て最短時間で理解できるように書かなければならない。」
これは著書「リーダブルコード」に記述されていた言葉。
この言葉を頭にいれてコードを書いていく。
意識すること
意識することは以下の3点
- 具体的な変数名・関数名が命名
- 複雑なロジックを避けた書き方
- 有用なコメント
読みやすいコードを書く理由
- 個人・組織の生産性が上がる
- 保守性が上がる
- 柔軟な開発体制が構築できる
これらを実現するためにリファクタリングを行う。
リファクタリング
実装した機能に影響を与えず、ソースコードを読みやすいように改善すること。
リファクタリングをすることで、実装されているコードの理解や修正が容易になる。
どちらのコードが読みやすいか
意識することを見て、以下のコードはどちらが読みやすいコードと呼べるのか。
例:A
const getYear = (year) => {
if (year % 4 == 0){
if (year % 100 == 0 && year % 400 != 0){
console.log(`${year}年は閏年ではありません`);
} else {
console.log(`${year}年は閏年です`);
};
}else {
console.log(`${year}年は閏年ではありません`);
};
};
例:B
// yearが閏年かどうかを判定する関数
const isLeapYear? = (year) => {
if (year % 400 == 0) {
// 400で割り切れる年は閏年
return true;
};
if (year % 100 == 0) {
// 400で割り切れず、100で割り切れる年は平年
return false;
};
if (year % 4 == 0) {
// 400でも100でも割り切れず、4で割り切れる年は閏年
return true;
};
// それ以外は平年
return false;
};
if (isLeapYear?(year)) {
console.log(`${year}年は閏年です`);
} else {
console.log(`${year}年は閏年ではありません`);
};
さて、どちらが読みやすいコードと言えるだろうか?
答えをクリック↓
答え
答えは`B` 理由 - 変数名(関数名)が他者を考慮した命名 - 複雑なロジックがない - コメントによって全体像を把握しながらコードを読める変数と関数の命名
抽象的な名前は避けて、具体的な名前をつける意識することはこれだけ。
変数
例えば
const one = 1;
const userId = 1
この2つの記述を見て、どちらが具体的かは誰でも分かるはず。答えは2つ目の記述。
読み手が見て役割を把握できる変数名をつける。
関数
const add = () => {
// 処理
};
const addTask = () => {
// 処理
};
この2つの記述を見てどちらが具体的か、これも簡単なはず。答えは2つ目の記述。
関数名は動詞+名詞を意識する。
ロジックの単純化
const getYear = (year) => {
if (year % 4 == 0){
if (year % 100 == 0 && year % 400 != 0){
console.log(`${year}年は閏年ではありません`);
} else {
console.log(`${year}年は閏年です`);
};
}else {
console.log(`${year}年は閏年ではありません`);
};
};
上記コードをリファクタリングしていく。
まずはネストの中のネストを避ける。このコードの場合、if分の中のif文を避ける。
const getYear = (year) => {
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
console.log(`${year}年は閏年です`);
} else {
console.log(`${year}年は閏年ではありません`);
};
};
論理演算子を用いてifの中のifを回避。
う〜ん。まだまだ、改善の余地あり。
条件式の記述が長い場合、読みづらさを改善するため関数化する。
const isLeapYear? = (year) => {
return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
};
if (isLeapYear?(year)) {
console.log(`${year}年は閏年です`);
} else {
console.log(`${year}年は閏年ではありません`);
};
条件式を分解
const isLeapYear? = (year) => {
if (year % 400 == 0) {
return true;
};
if (year % 100 == 0) {
return false;
};
if (year % 4 ==0) {
return true;
};
return false;
};
if (isLeapYear?(year)) {
console.log(`${year}年は閏年です`);
} else {
console.log(`${year}年は閏年ではありません`);
};
かなり分かりやすくなった!!
ここまで行ったこととしては
- ifの中のifを避ける →論理演算子の使用
- 条件式を短くする→条件式の関数化
- 複数の条件式を分解する→複数のif分に分ける
コメントによる全体像の把握
コメントの目的は実装者の意図を読み手に伝えること。
// yearが閏年かどうかを判定する関数
const isLeapYear? = (year) => {
if (year % 400 == 0) {
// 400で割り切れる年は閏年
return true;
};
if (year % 100 == 0) {
// 400で割り切れず、100で割り切れる年は平年
return false;
};
if (year % 4 == 0) {
// 400でも100でも割り切れず、4で割り切れる年は閏年
return true;
};
// それ以外は平年
return false;
};
if (isLeapYear?(year)) {
console.log(`${year}年は閏年です`);
} else {
console.log(`${year}年は閏年ではありません`);
};
コメントにより、コードは長くなってしまうが、流れは理解しやすくなっている。
しかし、ただコメントを書けばいいということでもないのでコメントを書く際に気をつけることは以下とする。
- 複雑なロジックを記述した場合、処理の概要と自分の考えをコメントする
- なぜその処理をしているかコメントする
- コメントは1文で済ませる
- コメントが1文で済まないようであればソースコードを直すべきである
終わりに
これを見て違うなぁと思う人もいる。やり方は様々で絶対的な正解はない。
ただ、自分も含め、初学者が初学者なりに前提として頭に入れておくことは初めに述べたこの言葉。「コードは他の人が見て最短時間で理解できるように書かなければならない。」以上。