Web制作、Web開発の歩き方

分かりやすいコードの書き方

第8話:変更に強いコードの設計

(最終更新日:2025.4.30)


分かりやすいコード

この記事は5分で読めます!
(絵が小さい場合はスマホを横に)

変更に強いコードへ!

「仕様変更が入った瞬間、あちこちのコードを書き直す羽目になった」 そんな経験はないだろうか。 分かりやすく、保守性が高いコードを目指すなら「変更に強いコード」という視点は欠かせない。 今回は、それを実現するための基本原則と設計アプローチを紹介する。



1.OCP(オープン・クローズドの原則)とは

OCPに関しては、以前もいくつか記事を書いている。 ここにリンクを貼る。 開放/閉鎖の原則(1)システムの拡張性を保つ設計方法開放/閉鎖の原則(2)継承とポリモーフィズムの活用。 この考え方を簡単に記すと「拡張に対しては開いているが、修正に対しては閉じているべき」になる。 つまり、新しい機能を追加するときは、既存のコードを変更せずに対応できるようにする。 そして、条件分岐を増やさずに、処理の追加は差し替えや継承・委譲で対応すると言うことだ。 言葉だけ聞くと分かりにくい。例で示そう。下記は悪い例になる。 この書き方だと、ユーザーの種類が増える度に関数を書き直さなくてはならない。

悪い例

次に良い例を示す。dictionaryを使って、ユーザーの種類と割引率を示している。 この書き方であれば、ユーザーの種類が増えたとしても関数自体を変える必要がない。 変えるのは、dictionaryの部分だけである。しかも、同様に種類と値を追加して書くだけなので、非常に分かりやすい。 これだけでもOCPの優位性は伝わるだろう。

良い例

2.関数型 vs 手続き型:どちらが変更に強いか

関数型と手続き型、どちらが変更に強いか。 この問いに対しては、関数型の方が強いと答える。 ただし、組み込みや状態制御を行う場合は、手続き型でないと実装が難しい場合が多い。 なので、臨機応変にコードを書いていけばよい。手続き型でも書き方次第で変更に強いコードにはなる。

関数型と手続き型の比較

タイプ 関数型 手続き型
状態管理 状態を持たない(不変) グローバル変数や状態に依存しがち
副作用 少ない(純粋関数) 多くなりがち
再利用性 関数合成でしやすい 流れの中で再利用しにくい
初期学習コスト やや高い 低い(慣れやすい)


3.変更の影響範囲を最小限に抑える方法

変更の影響範囲を最小限に抑えるには、次の4点を押さえよう。 1、3、4は今までも良く言ってきたことだ。2はPythonのコードでは特に重要だ。 使い方も難しくないので、本項の1を参考に、ぜひマスターしよう。

  • 関数を小さく・明確に分ける : 1つの関数の責任を小さくすることで、修正時の影響を限定
  • 条件分岐をデータ化・構造化: if文を増やすより、辞書やマッピングで処理を抽象化
  • インターフェースや抽象化に依存: 直接具体クラスを使わない。抽象に依存する
  • 変更に備えたレイヤー構造にする: UI / ロジック / データアクセスを分離、クリーンアーキテクチャを使う
4.データ駆動設計とは

データ駆動設計とは「コードを書かずに振る舞いを変える」設計のことだ。 例えば、設定ファイル(JSON、YAML)でフローや閾値を変更する。 これにより、下記のメリットが得られる。

  • 振る舞いを コード変更なしで切り替えられる
  • 非エンジニアでも設定が可能
  • テストや本番環境での運用フレンドリーな作りになる

実際にJavaScriptでデータ駆動設計すると、以下のようになる。 最初に定義したdiscountRulesの部分がデータ駆動になる。 これを引数にして、関数が機能する。 executiveというユーザータイプ(type)、割引率(rate)0.15という新たなルールを加えることだって容易だ。

データ駆動設計を用いた例

5.まとめ

今回は変更に強いコードについて紹介した。 OCPの法則、関数型の採用、条件分岐を避け、構造化・データかする、データ駆動設計という手段をとることで、 変更に強いコードを実現することができる。 そして、今回はOCPの中でもデータ駆動設計を中心に説明した。 データ駆動設計は、非エンジニアでもメンテナンス、拡張が可能である。ぜひ、これを機に使ってみよう。

▼参考図書、サイト

 「リーダブルコード」 Dustin Boswell、Trevor Foucher 著、角 征典 訳 オライリー