保守性の高いコードがなぜ必要とされるのか?そのためにやるべきではないこと

もう何年もコードを書く仕事をしていますが、どうすれば保守性や可読性の高いコードなのかは、毎日試行錯誤しています。

じゃあ保守性や可読性の高いコードって何よ?ってなるとパッと説明しづらいですが、Badプラクティスは結構あるかと思います。

特に初心者のころはコードレビューでこのあたりの指摘をよく受けました。

本記事では、保守性や可読性の高いコードを書くためにやらない方が良いことを紹介します。

なぜ保守性が高いコードが必要とされるのか?

保守性が低いと生産性の低下につながるため

1つは、中長期的にみたときに生産性が下がる可能性が高まるためです。

例えば、ユーザーの一覧データの配列を保持する変数名を下記のようにしたとします。

// Good
const users = userList;

// Bad
const result = userList;

どちらも短期で見た場合は、きちんと動作しますしこの時点では実装した瞬間は特に生産性には変化はありません。

しかし、ここのコードを2ヶ月後に変更することになりコードをみたとき、「result」って何が入ってるんだ?となりかねません。可読性が悪いといえます。

これが数行ならいいですが大量のコードであれば解読するのにもコストが掛かりますし、意図しない不具合にも繋がりかねません。

このように、可読性が悪いことで後々の開発コストが上がってしまうことは十分にありえます。

保守性が低いコードの例

保守性の例では、ページAで使っている問い合わせフォームをページBでもつかうことになった場合に、ページAの処理をページBにコピペしたとします。この時点では一見早く実装できたように見えます。

しかし、将来的にこれが20箇所のページでつかうことになり、しかもその後全てのページでフォームに項目を追加したいとなった場合、同じ処理を20箇所で書かないといけなくなってしまいます。

共通部品化しておけば1箇所で済んだのに、といったケースです。

このように、コードは動作することが大切ですが普遍ではなく日々変化するものです。そのため、未来の自分を含めて様々な人が読むことが大前提になり、読みやすく保守しやすいコードでないとこのように生産性を下げることにもつながってしまいます。

もっと言えば、保守性の低いプロダクトというのはいわば地雷だらけのコードになります。エンジニアからしたら楽しい環境とは言えないので、モチベーションの低下にもつながってしまうなど、負の連鎖を生むことも少なくありません。

もっと詳しい保守性や可読性の重要性

他にも、保守性の重要性について詳しく書いている記事がありますので共有しておきます。

エンジニア歴17年の俺が、事業系の開発タスクをバンバン投げてくる非エンジニアに、保守の必要性を死ぬほど分かりやすく説明する。|みやたけ|note

技術的負債 – Qiita

保守性や可読性を下げないためにやらない方が良いこと

ここから保守性の高いコードを維持するために「やらないほうがいいこと」を紹介していきます。

意味の広すぎる変数名やメソッド名をつけない

変数名は短すぎる名前や抽象度の高い名前はつけないようにしています。コードを読み直したときに、「このarrayって何がはいってるんだっけ?」となってしまい可読性が下がります。

// 意味が広すぎて何の配列かわからない
const array = shop.list;

// データの内容がわかる変数名になっている
const shop_list = shop.list;

なるべく具体的な名前をつけてデータの内容が予測できるようにしましょう。

省略形の使用は極力避けること

極力省略形は避けましょう。自分にとってはわかりやすくても、他人には全然別の単語と捉えられてしまう可能性があります。

ただし、明らかに長い名前で省略形のほうがチーム内に浸透している場合などはこの限りではありません。

// 省略形では、何を表すのかわかりにくい
const addr = getAddress
const svr = getServerName

// 省略せずに書くことで誤解を減らすことができる
const address = getAddress
const serverName = getServerName

名前と目的があっていない名称をつけない

こんなのないやろ、と思うかもしれませんがレガシーコードでは意外とよくあるのです。

目的に合っていない変数名もトラブルの原因になるのでやめたほうが良いです。第3者が読んだときにもわかりにくいですし、自分が後から読んだときにもわからなくなってしまいます。

// ユーザーリストにショップデータを格納している
const USER_LIST = fetchShopData;

不必要にコメントはつけない

変数名から推測できるような内容や、当たり前すぎる内容はあまり価値のあるコメントではないのであまりつけないようにしています。

逆にコメントすべき点は、コードから読み取れないような「なぜ」の部分や課題点を書くことです。こうすることで開発者に気づきを与えることができるのでおすすめです。(無論そうしたコードがないことが望ましいですが、、、)

// 引数をもとにURLを生成します <- そのまますぎるのであまり意味がない
function generateUrl(string) {
} 

// TODO: この処理の課題や後ほど修正したい旨など
function hoge() {
}

関数名では曖昧な表現を避ける

関数名には上記のルールでつけるようにしています。さらに、可能な限り曖昧な意味の単語は避けて具体的な処理内容を表す単語を使うようにしています。

# 曖昧な表現
function getPage() {
}

# 具体的な表現
function downloadPage() {
}

コメントで関数の説明をしない

関数名をうまくつけられないので、コメントで補足するということは辞めたほうが良いです。この時考えるべきなのは、わかりやすい関数名を考えるか、そもそも関数を分割できないかどうかを考えるようにしています

酷いコードに優れたコメントをつけるよりも、優れたコードを書くことを意識しましょう。

1つのメソッドの中で複数の処理を書かない

いわゆる単一責任の原則とも言えます。

例えば、1つのメソッドの中で、データの取得、整形と2種類と複数の処理を行っている場合、2種類のメソッドに分けてそれぞれを呼び出すように書くほうが良いです。

function fetchShopList{
  # ショップ一覧情報を取得する 
  # 取得したデータを整形して返す
}
fetchShopList;

------------------------------------------------------
  
function fetchShopList {
  # ショップ一覧情報を取得する	
}
function shapeShopList(shopList) {
  # 取得したデータを整形して返す	
}

const shopList = fetchShopList;
shapeShopList(shopList);

このように分けることで可読性や再利用性が高まることはもちろん、自動テストなどを書いている場合はテスタビティ(テストのしやすさ)も向上します。

設計や命名を一人だけで決めない

すべてというわけではありませんが、テーブル名や共通処理の名前、設計レベル(どこに処理を書くべきか)などはなるべくチームのメンバーと命名については相談して決めるようにしています。

なぜこの命名にしたのか、この処理をどこに書くべきかといったことは知らず知らず保守性を下げて、プロダクトを汚してしまう可能性があります。第3者の意見をとりいれることでぐっとその可能性が減らせます。

また、問題なくても自身がつきますし、別の設計になったとしても、それはより洗練された設計にできるので相談するメリットは非常に大きいと思っています。

まとめ

以上、保守性の必要性と、保守性の高いコードを書くために気をつけていることでした。

  • 意味の広すぎる名前をつけない
  • 省略形は極力避けること
  • 名前と目的があっていない名称をつけない
  • 不要なコメントはつけない
  • 関数名では曖昧な表現を避ける
  • コメントで関数の説明をしない
  • 1つのメソッドの中で複数の処理を書かない

また、コードを本格的に書き始めるときは下記の書籍をよく読んでいました。今でもたまに読み返す名書です。

O’Reilly Japan – リーダブルコード

最後まで読んでいただきありがとうございます!