TOP > プログラマ2.0日報 > マジックナンバーは7だっけ?

あすなろBlogger

facebookに投稿 このエントリーを含むはてなブックマーク このエントリーを含むはてなブックマーク このエントリーをはてなブックマークに追加 この記事をクリップ! livedoorclip ユーザー数 BuzzurlにブックマークBuzzurlにブックマーク この記事をtweetする

マジックナンバーは7だっけ?

2008.06.11

有名な話かなあ...とも思うのですが、

魔法の数字=7(あるいは7±2)

というのをご存知でしょうか?これは心理学で(→引用元

「魔法の数7±2:我々の情報処理能力の幾つかの限界」。この研究では、ランダムな数字の並びを被験者に記憶させ、後に正確に反復できるかを見ることで、どの程度の情報量を人は一度に記憶できるのかを繰り返し試験した。その結果、このマジックナンバーが判明するわけだが....

という結果があって、「人間が特に意識せずに、間違わずに処理できる最大の数が7±2だ」という結論を一般に導くものです。ですから、これを受けて、よくコーディング規約で

引数の数の最大は7

という規約が採用されることになります。

とはいえ....結構実際のプログラムでは、そうも言ってられないこともあります。勿論、

引数があまりに増えちゃったから、それをまとめる情報渡しの構造体(とかクラス)を作って、間違えにくくしよう....

というリファクタリングをするのはとても良いことです。

で....ですが、「現実に最大どのくらいの引数が渡ってるの??」というのは、また 別の問題です。勿論

引数の数の最大値

が言語(orコンパイラ実装)によってはないわけでもないでしょう。私が知ってる範囲だと、C言語規格の「翻訳限界この限界を超えたらコンパイルできなくても、そのコンパイラは「規格に合致している」と主張できる最大値)」は、31個です。じゃあ、Java だとどうだろう...と調べてみましたが、記述が見つからないようです。ひょっとして無制限?と思って、引数 200 個のメソッドを定義してみましたが、全然コンパイルも実行も問題ありません。まあ引数200個で問題がないのならば、現実的に「無制限」と捉えてよいでしょう。

では、現実的に...で考えると、

Java の標準ライブラリではどういう引数の数の分布をしているか?

が参考になるのでは、と思います。「Java: 利用可能なクラスを一覧する」で紹介したやり方を基に勘定してみました。範囲は Java5 の java.*, javax.* パッケージの public なクラスの public なメソッド(とコンストラクタ)で見るのが公平というものでしょう。

結果は、

 数   メソッド (%) コンストラクタ(%)
0 8215(41.57) 844(28.83)
1 7591(38.41) 1030(35.19)
2 2220(11.23) 556(19.00)
3 946(4.79) 211(7.21)
4 322(1.63) 131(4.48)
5 162(0.82) 63(2.15)
6 206(1.04) 45(1.54)
7 54(0.27) 19(0.65)
8 27(0.14) 10(0.34)
9 4(0.02) 6(0.20)
10 7(0.04) 2(0.07)
11 5(0.03) 6(0.20)
12 2(0.01) 0(0)

となって、最大引数12個のメソッドがあり、コンストラクタの場合は11個が最大になります。で...やはり6個を境にして、それ以降はぐっと減ります。やはり「魔法」の伝説は事実のようですね。

ちなみに栄えある最大引数のメソッドは、

javax.swing.plaf.synth.SynthGraphicsUtils#layoutText
javax.swing.SwingUtilities#layoutCompoundLabel

で12個も引数があります....まあ、GUI関連はどうしても引数が多くなる傾向がありますよね。ちなみに、「public クラスの public メソッド」という制限を外すと、

javax.swing.plaf.synth.SynthMenuItemUI#layoutMenuItem

がなんと 22 個!の強烈な数を取ります。お姿は、

    private static String layoutMenuItem(
        SynthContext context,
        FontMetrics fm,
        SynthContext accContext,
        String text,
        FontMetrics fmAccel,
        String acceleratorText,
        Icon icon,
        Icon checkIcon,
        Icon arrowIcon,
        int verticalAlignment,
        int horizontalAlignment,
        int verticalTextPosition,
        int horizontalTextPosition,
        Rectangle viewRect,
        Rectangle iconRect,
        Rectangle textRect,
        Rectangle acceleratorRect,
        Rectangle checkIconRect,
        Rectangle arrowIconRect,
        int textIconGap,
        int menuItemGap, boolean useCheckAndArrow
        )
    {

という強烈なものです....呼び出しも、

        String text = layoutMenuItem(context, fm, accContext,
            b.getText(), accFM, acceleratorText, b.getIcon(),
            checkIcon, arrowIcon,
            b.getVerticalAlignment(), b.getHorizontalAlignment(),
            b.getVerticalTextPosition(), 
            b.getHorizontalTextPosition(),
            viewRect, iconRect, textRect, acceleratorRect,
            checkIconRect, arrowIconRect,
            b.getText() == null ? 0 : defaultTextIconGap,
            defaultTextIconGap, useCheckAndArrow
        );

と Java 離れしてますね!

投稿者 : 杉浦 こずえ | 投稿日時 : 2008.06.11 14:44

あすなろBLOGのトラックバック・コメントは承認制になっています。
すぐにブログに反映されませんので、ご了承ください。

トラックバックURL


コメントの送信








カレンダー

<< 2008年06月 >>

1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30          

最新のエントリー

最新のトラックバック

最新のコメント

Tag

バックナンバー