• ホーム
  • Techブログ
  • プログラミングは手紙のように ~メンテナンス性の高いソースコードの工夫~

プログラミングは手紙のように ~メンテナンス性の高いソースコードの工夫~

技術グループ
技術グループ
プログラミングは手紙のように ~メンテナンス性の高いソースコードの工夫~

こんにちは、萩田です。

今回はプログラムのメンテナンス性についてのお話をしたいと思います。

弊社ではクラウドサービスを運営するにあたり、メンテナンス性を考慮したコーディングに気を付けています。

具体例を挙げながら、そのエッセンスをお伝えできればと思います。

Question: 味噌汁の作り方

質問:「味噌汁の作り方教えて?」
回答:「先に湯沸かしといて野菜切って湯湧いたら味噌入れて具入れて沸騰させないであと換気扇を最初に回してあと味噌がないからまず買ってきて」

突然でしたが、「味噌汁の作り方」についての回答はわかりやすいでしょうか?

なかなか理解しにくい回答だったと思います。

しかし、こういったコードを書いてはいませんか?

・・・というのが、本稿の問いかけなのです。

あなたの書いたソースコードは、『プロダクトライフサイクルにあった、メンテナンス性を担保する可読性』を確保できているでしょうか?

無理やりなワンライナー


まずはじめに以下のコードをご覧ください。

改善前

const result = (a => b => c => a > 0 ? (b > 0 ? "A" : "B") : (b > 0 ? "C" : (c > 0 ? "D" : "E")))(a)(b)(c);

こちらは意味がわかるでしょうか?

先ほどの味噌汁の例題と同じく、解読するのが大変だと思います。

これをわかりやすく書き換えると、以下のようになります。

改善後

function getResult(a, b, c) {
  if (a > 0) {
    if (b > 0) {
      return "A";
    } else {
      return "B";
    }
  } else {
    if (b > 0) {
      return "C";
    } else if (c > 0) {
      return "D";
    } else {
      return "E";
    }
  }
}

const result = getResult(a, b, c);

いかがでしょうか?

改善前のコードはワンライナーで無理やり短く書いたのですが、それですとメンテナンス性が落ちてしまいます。

弊社では後者のように、『メンテナンス性の高い、可読性の高い』コードを推奨しています。

これを手紙でたとえると

あらためて、さきほどのコードの例を手紙に例えると、改善前のコードは、以下のようなやりとりをしているようなものです。

質問:「味噌汁の作り方教えて?」
回答:「先に湯沸かしといて野菜切って湯湧いたら味噌入れて具入れて沸騰させないであと換気扇を最初に回してあと味噌がないからまず買ってきて」

こう言っているのと同じことです!

つまり、プログラムのソースコードというのは、未来の自分に対して、あるいは後から読む人にとっての、手紙のようなものなのです。

コードの冗長性=ミニタワーPCの配線

前述の例ですとあまりに極端かもしれませんが、日常でも『無理やりワンライナーになっているコード』などを見かける場合があります。

私の見解では、『エンタープライズなシステムでは、簡潔にしすぎず、一定の冗長性=配線の遊びが必要』と考えています。

ここで、『自作フルタワーPCとメーカー製ミニタワーPCの比較』を例にしてみたいと思います。

PCの種類

配線

プログラムの場合

自作フルタワーPC

遊びがあり検証しやすい

調査・デバッグしやすい

メーカー製ミニタワーPC

最短配線で動かせない

調査・デバッグしにくい

Aはフルタワーの筐体を元に自作PCを組んだケースでして、この場合、配線やパーツの隙間があり、問題が起きたときに部分交換や検証がしやすい。(これは例えば、工場の大規模な工業機械みたいなものかもしれません。機械のある歯車が故障した際、あまりにタイトな機構だとそれすら難しいのですが、『余白やメンテナンス性』を確保しておくことで、簡単に部品交換ができるようになります)

けれどBはメーカー製のコンパクトなPCです。配線などがタイトであるため、故障が発生したときに、ケースを開けて検証したり部分交換したりするのは難しい。

このように、ABの選択肢がある場合、SaaS運営においては通常、Aの方が適していると考えています。

例えば一例ですと、以下のようなアロー関数を利用したワンライナーがあったとします。

const calculate = (a, b) => ({ sum: a + b, difference: a - b, product: a * b, quotient: a / b });

これはこれでメリットがあると思いますが、エンタープライズの現場では『遊びがなさすぎてイレギュラー時に対処しづらい』ということになります。

例えば、稼働中の本番環境において『変数bの中身がなにかおかしいぞ!』と兆候を掴めたとして、『じゃあbの中身をデバッグするぞ』となった場合、

const result = calculate_function(a, b);
function calculate_function(a, b) {
  const result = {
    sum: a + b,
    difference: a - b,
    product: a * b,
    quotient: a / b
  };
  return result;
}

こんな感じに書き直さないとロジックを理解できない場合があります。

(緊急時は認知バイアスの影響で、単純な論理的思考が阻害されてしまいます!)

このため、『重要な責任を担うエンタープライズシステム・医療系システムなどでは、あえて冗長な記述をする』

ということが正解となる場合もあると思います。

これは『戦場のノウハウ』であり、あまり一般的に言われないことかも知れませんが。

目的ごとのソースコードの特徴

世の中には様々な背景や目的で書かれたソースコードがあります。

ざっと、以下のような種類があると言えるでしょう。

  • 書籍などのサンプルソース:
    → 省スペースであることが求められる
    (エラー処理などを省略し、論点にフォーカスしている)
    →「ワンライナーでかっこよく」書かれている傾向がある
  • PoC用途のコード:
    → 最短の開発投資でアウトプットを得ることが目的
    → 長期運用では、負荷対策や可読性で問題がある場合がある
  • エンタープライズプロダクト:
    → 長期運用を重視した、厳密なコーディング規約に乗っ取った書き方

このように、シチュエーションによって様々な特徴のあるソースコードが存在します。

プロダクトの特性やライフサイクルに応じた、適切な書き方を採用すべきではないでしょうか?

プロダクトライフサイクルと開発投資のアーク

ソースコードについて、どれくらいのメンテナンス性をもたせるべきか、という論点で整理してみます。

以下は、開発工数に対してどれくらいの保守工数がかかるか、というシミュレーション表です。

シナリオ

開発工数(p1)

年間保守工数(p2)

初年度工数(p3 = p1 + p2)

5年運用時工数(p3 + (p2 * 4))

A(雑に早く作る)

10h

30h

40h

【160h】

B(丁寧に作る)

20h

10h

30h

【70h】

結論としては、

『5年時総工数:A(雑)は160h。B(丁寧)は70h』

となり、Bの方が大幅に工数が低いということになります。

整理するとこういうことです↓

  • 修正が年間10回、1度の修正に3時間かかる場合、仮に開発工数が倍かかってでも、保守工数を三分の1に下げた方がトータルでは少ない工数で保守できる。
  • 長期利用するプロダクトほど、この傾向が顕著。
  • 特に自社クラウドサービスなどは、10年レベルで考えるべき。

長期運用するプロダクトほど、メンテナンス性に投資した方が効率がよい、ということですね。(当たり前かもしれませんが)

『作るのは一瞬、保守は10年!』ということです。

同時にこの視座は、『フレームワーク選定時、初期コストとメンテナンス性、機能とコード量をどのバランスで考えるべきか』という論点もはらんでいます。

サービス運営においては解析スピードが重要

特に自社サービスを運営する場合、メンテナンス性・可読性・保守性は重要な要素となります。メンテナンス性は保守のスピードに直結します。

ちょっと想像してみてください。

あなたの担当した開発箇所でバグが発生しました。

電話がずっと鳴り響き、社内からも質問攻め。そんな中で1分でも早く問題箇所を特定して、修正しなければならない。場合によってはセキュリティに関わる問題かもしれない・・

こんなときに、落ち着いてデバッグするのは至難の技です。

ちょっとしたif文みたいなものも、複雑な条件が少し含まれるだけで、人間の判断速度が落ちていきます。

だからこそ、『可能な限りシンプルに、わかりやすく』コーディングすることが重要なのです。

メンテナンス性のチェック項目

自分でのセルフチェック、またはソースコードレビューの際に、以下のようなチェックを行うと有効だと思います。

  • 再読なしに理解できるか?
  • 1行1秒で理解できるか?
  • 独りよがりの手紙を書いていないか?
  • 技術書や参考サイトのコピペになっていないか?

こんなことに注意して、『素敵な手紙名人』になりたいものです。

今回は「プログラミングは手紙のように ~メンテナンス性の高いソースコードの工夫~」ということで、ソースコードのメンテナンス性について書かせていただきました。

いかがでしたでしょうか?

みなさんの参考になれば幸いです。

記事を書いた人
技術グループ
技術グループ
GMOリザーブプラス
は一緒に働く仲間を募集しています