良いコードの原則 ~ヒトの認知的限界「マジカルナンバー4」~

スポンサーリンク

対象読者

  • オブジェクト指向の原理原則が取っ付きにくい方
  • ドメイン駆動設計(DDD)などのプラクティスを使用してもコード品質が良くならないと感じている方

結論

コーディングスタイルはプログラマの宗派・思想・趣味嗜好の数だけ存在する。当然、みんな違ってみんない良い訳ではない。良い方法はプログラミング原則または無数のテクニックとしてまとめられていたりいなかったりする。

どれが最善の方法なのかも分からないし、そもそも良い手法を理解すること自体も難しい場合がある。例えば、SOLIDの原則やらデザインパターンは抽象的で難しい。

しかし、人間がプログラムを読み書きする以上、良いプログラムは人間の認知能力に則したもののはずだ。故にリーダブルであることが良いコードの条件と一般的に言われる。ただ、リーダブルという指針も抽象的で応用しづらい。

そこで、本稿は良いプログラムを書くための具体的かつ明解な原則を提案する。すなわち、「一度に把握すべき情報の数をマジカルナンバー4以下にせよ」だ。常に4個程度の情報にブレークダウンできる構造にせよ、とも言い換えられる。

マジカルナンバー4;ヒトが把握できる情報の数

マジカルナンバーとは、人間が短期記憶に保持できる情報の数だ。一度に把握できる要素数の上限とも換言できるだろう。マジカルナンバーには以下のように2つの説がある。

  • マジカルナンバー7:マジカルナンバーは7±2とする説(1956年)
  • マジカルナンバー4:マジカルナンバーは4±1とする説(2001年)

新しく提唱されたマジカルナンバー4の方が妥当とされているようだ[1]。さらには近年では「マジカルナンバー4」の最小の数字である「マジカルナンバー3」も浸透し始めているらしい[2]

このように、意外にも人間が把握できる情報量は少ない。聞き慣れない概念や業務内容についての話が理解しづらいのも当然だ。同様に巨大なメソッドやクラス、トランザクションスクリプトも理解しづらい。

情報のかたまり「チャンク」

ヒトは高々4個程度の情報しか一度に扱えないらしい。あれ?おかしくないだろうか。それにしてはコミュニケーションが高度過ぎやしないか。ちょっとした短文でも大量に情報がやり取りできる場合もあるし。

雑にマジカルナンバーを説明してしまったことをここに謝罪する。より正しくは「人間が短期記憶に保持できるチャンクの数」だ。

チャンクとは「情報のかたまり」のことで、大小さまざまだ。大きいチャンクを用いることで高度な(多くの)情報伝達が可能となる。チャンクを大きくすることを「抽象化」と呼んだりする

チャンクを大きくする例:電話番号

電話番号は11桁程度の数字の羅列だ。すでにマジカルナンバーを超えてしまっているので、ヒトが電話番号を覚えるのは容易ではない。そこで「xxx-yyyy-zzzz」みたいに番号を3つにグルーピングする。つまり、11個のチャンクをマジカルナンバー以下の3つのチャンクにまとめると把握しやすくなる。

プログラム言語はチャンクを大きくするための仕組み

プログラムの一番低級な表現は機械語(0か1のバイト列)である。無機質なバイト列はすぐにマジックナンバー以内で扱いきれなくなる、人間には理解困難であり、まさに機械のための表現だ。

そこで人間が理解し易い表現が要請された。そして発明されたのが高級言語、いわゆるプログラミング言語だ。高級言語を使用する時点で、ソースコードをリーダブルに書くことが自動的に目標となるはずだ。

故に、高級言語(特ににオブジェクト指向の)では大きなチャンクを扱う(抽象化の)ための機能が提供されている。

  • データ型(プリミティブ型)
  • 関数
  • クラス(or 自作データ型)
  • インターフェース(or 抽象クラス)
  • etc.

たとえば、プリミティブ型のInt型は32バイト(32チャンク)を整数という1チャンクとして扱えるようにしてくれる。関数は複数の手続きを1つにまとめる。クラスはデータと手続きを1つにまとめる。インターフェースは個別の具象クラスを同一視する。

しかし、これらの機能は抽象化という目的からは誤用されることが多い。以下ではマジックナンバーの原則のアンチパターンを列挙していき、本旨を裏付けていく。

アンチパターン1;4つ以上の引数をもつ関数・メソッド

引数が4,5個くらいある関数は使いづらいし読みづらい。引数の何番目に何の値を入れればいいんだっけ?となる。引数が3個でもちょっと多いかなと個人的には感じる。なぜなのだろうか。

関数の外面?は以下の3要素で決まる。内部の詳細を気にせずに関数を使用するために把握すべき情報とも言い替えられる。

  • 関数名
  • 引数の型
  • 返り値の型

すでに関数名と返り値の型で2チャンクを占められているため、

追加機能はモデルを再設計する機会 いふ文とかで誤魔化さない

機能の共通化までの視点しかない
責務を明確に定義する
前者にはドメインを深く捉えたモデルを構築しようとする気概がまだない。うまく処理を分割して、インターフェースによって切り替えを行うことはできない。保守のときに、この機能を変更、追加したいという要望に対して、前者には応えられない。共通化という視点だけでは、長いメソッドでも無頓着に許容してしまう恐れがあるから。

  • マジカルナンバー
  • 同時に認識するチャンクを常に7個以下にする
  • チャンクを大きくする仕組み:関数、クラス
  • 手続き型の限界
  • 継承の限界
  • 関数は20行程度にすべし
  • クラスのメンバは7個以下にすべし

参考

  1. マジックナンバー7±2の間違いと真実
  2. マジカルナンバー7±2(ミラーの法則)

コメント

タイトルとURLをコピーしました