見出し画像

君、引数いくつ渡したことある?

いつもご覧いただきありがとうございます。
もしくは初めて見た方は、数ある記事の中からコイツ選んでくれて嬉しいです。
ゼバ会です。

今回、タイトルに惹かれてクリックしてくださった方は、まず間違いなく本職のプログラマーの方々でしょう。
そのタイトル通り、今回はプログラムを書く際にやってしまいがちな、やたら引数を増やすという行為に関する功罪について考えます。
言うまでもなく、メソッド引数の数のみに限定した話題ではなく、メソッド間・クラス間・モジュール間など、データの渡し方が必要なあらゆる場面に関する話です。

世の中には、ほぼ無数に数限りない種類のプログラムがあるので、たまにはこんなのがありますよね。
数十種類以上ものデータを非常に複雑な処理を経由し、アッと驚くような形にして出力するヤツとかね。

たとえばですが、前回は例示として、勤務時間を計算するのに必要な入力データ一覧というのを掲載しました。

1. 本人の出勤データ
2. 本人の勤務予定情報
3. 会社の有給休暇情報
4. 会社の特休制度に関する情報
5. 出向先の会社情報
6. 出向先との労働契約情報
7. 本人の有給休暇申請
8. 本人の特休休暇申請
9. 会社の振休/代休制度情報
10. 本人の振休/代休の取得状況

勤務時間というたった1つの数字を出力するだけのために、これだけのデータが必要という例です。
もし仮に、上記のプログラムを実際に書くとしたら、その計算を行うメソッドは引数が10個必要なのでしょうか。

そんなことしたらプログラムがグチャグチャになりますよね。
てか、たしかに1つ1つのデータは絶対に必要かもしれないけど、だからって全て同時に必要なわけじゃないはずですよね?

なぜならプログラムというのは、必ず1ステップずつ順番に行うものだからです。
ですから、データはいつでも必ず、1つずつ順番にしか必要とならないはずです。
これは常に必ず同じなのですから、そもそも論として「複数種類のデータが同時に必要」という状況がおかしいと思うべきです。

〇なぜ大量のデータ受け渡しをしたくなるのか

このことは、普段から優秀な人材に囲まれて仕事をしている人には、むしろピンと来ないかもしれません。
世の中には、大量のデータ受け渡しがどうしてもやむをえないとしか思えない状況、というのがあるのです。

たとえば以下の処理では、ユーザー情報が頻繁に登場します。
(処理内容には意味はないので細かく追いかける必要はありません。ユーザー情報が極めて頻繁に登場する例、とだけ理解してください)

ユーザー情報が全体に渡って引き回される処理例
1. ユーザー情報をデータベースから取り出す
2. ユーザーの社員番号と紐づく勤務データを取りだす
3. 勤務データに関する計算を行う
4. ユーザー情報が持つ雇用契約情報から、所定労働時間を取得して計算結果と比較
5. 有給休暇の取得処理を行う
6. ユーザー情報が持つ雇用契約情報から休暇管理情報を取り出し、有給休暇の妥当性をチェックする
7. ユーザー情報からメールアドレスを取得し、本人に結果を通知する

で、この処理を実際に書くとなった場合、中には「全ての処理が、ユーザー情報を引数に取っても仕方ない」と思う人もいるでしょう。
そういう人はおそらく、以下の考え方を持っているはずです。

前提1. データベースの入出力は重いため、なるだけすべきではない
前提2. クラスメンバー変数・グローバル変数のようなメモリー領域は、トレース時に見失いやすいので使用を避けるべきである

こういうパターンだけじゃないかもしれませんが、少なくとも上記2つの前提を持っている人は、大量のデータをメソッド間で引き回すことを「分かりやすさのためには仕方ない」と考えるでしょう。
データベースへのアクセスを本当の意味で最低限度にするため、プログラムの冒頭で大量のデータベースアクセスを1度に行い、結果取得されたデータを常に連れて回るわけです。

まぁ、何を隠そう昔の私なんですが、、、ww
当たり前ですが、こういうことをするからプログラムの品質が上がらないわけです。
でも本人は軽量で分かりやすいプログラムを書いているつもりですから、バグが頻発してもそれが自分のせいだとはまず気づきません。

これは、重い荷物を常に持ち運ぶカタツムリのような状態を、何でも持ってるから何でもできるオールマイティな状態と思っているのと同じです。
しかもその荷物は、ゴミ屋敷状態であらゆるものが詰め込まれているのです。
そりゃあたしかに、財産を全て持ち歩いていれば、いつどこで何が起こっても即座に対応できるのでしょうが、だからといってそういう状態を効率的と呼んでいいものでしょうか?
とても効率的ではないですよね。

で、こういう人がある日なにかを悟ると、今度は真反対に何も荷物を持っていないことがベストと考えるようになります。
(なりますてか、なりましたねww)
ちょっと前にミニマリストなる人達の生き方が少し流行しましたが、彼らの中にも荷物があっても整理できないからいっそ持たないという考えで、本来必要なものまで持たない(その結果周囲に迷惑をかける)人もいたようです。

もうお分かりですね。
何でも溜めこんで家をゴミ屋敷にしてしまう人と、必要な物まで捨ててしまうミニマリスト過多な人は、本質的に同じ問題を抱えている人達なんです。

つまり、どちらも物事を整理する力が弱いからなるのです。

〇必要な情報を必要な場所に置く、ということ

このような人達(つまり昔の私と同じタイプの若い子達)が、データ(とか自分の部屋とか)をちゃんと片づけできるようになっていくためには、どんな訓練が必要でしょうか。
私の場合、自分の整理能力を鍛えるためにまずやったのは、物はあらかじめ決めた場所にしか置かないというマイルールを徹底的に守ることでした。

たとえば「カバン」。
手にカバンを持っていて片手がふさがっているときに、両手が必要になったら、通常多くの人は適当な場所にカバンを置くでしょう。
私の場合、訓練のためにまずこれを禁止しました。

片手がカバンでふさがっているときに両手を使うためには、カバンを置いて両手を開けるだけでは事足りません。
その作業を行うために、カバンの存在を一時的に忘れる必要があるのです。
なぜなら、人間は2つのことを同時には考えられないからです。
そしてカバンの存在を意識的に忘れるということは、当然ですがその後思い出せなくなるリスクを負うということに繋がります。

ですので私の場合、忘れるリスクがあるときは、カバンを置ける場所があったとしてもあえて脇に挟みます。
カバンに限らず自分が持つありとあらゆる物は、そこに「置く」ためには「そこが定められた場所だから」という理由が必要なのであって、それ以外の理由で物を置いてはならないと自分に徹底したわけです。

そうすると当然ながら、何をどこに置くかという決め事を、ありとあらゆる物品に対してあらかじめ行っておく必要性が出てきました。
これは、ポストに投函された興味もないチラシにも適用されます。
興味のないチラシはチラシ捨て場以外の場所に置いてはならないし、もしチラシ捨て場が決められないなら、ずっと手に持っていなければならないわけです。
ですから、否が応でもチラシ捨て場をキチンと定義せざるをえません。

で、この考えが、プログラムの情報整理を行うときに役に立ちました。

コンピューター上のメモリーは私の自室とは違い、そもそも適当に物を置く場所なんてありません。
メモリーはOSに対してアロケートコマンドを投げたり、変数を宣言したりしなければ確保できないので、その意味で全てのメモリーはあらかじめ役割が決まっているわけです。
もちろん意識的に役割のないメモリー確保を行うこと自体は可能ですが、これは役割がないという役割を与えていることになるので本当の意味で役割がないわけではありません。

つまり、ユーザー情報が全体に渡って満遍なく必要となるプログラムの場合、

1. いつでも取り出せて
2. 持ち運びも便利で
3. あとから見ても誰も混乱しない

といった場所を決めて、そこにしか置いてはいけないことになります。
引数を使って全てのメソッドで引き回すのは、上記のうち 2. の条件を満たしません。
なので今回のユーザー情報の例であれば、今の私だったら「キャッシュ機能つきのスタティックな領域」に置くでしょう。

そのような意思決定を行う練習をすることで、引数で引き回さない選択を自分に許せるようになったわけです。

変数は「ローカル変数」「クラスメンバー」「オブジェクトのプロパティ」「スタティックメモリー」「グローバルメモリー」「セッション」などなど、様々な場所に置くことができます。
選択肢はこれだけあるわけですから、面倒くさいからといって何でもローカル変数に置いておけばいいわけではありません。
また、とりわけグローバル変数は利用がはばかられるケースが多いですが、だからといって何が何でも死に物狂いで使用を阻止する必要もないのです。

ですが反面、データというのはどこに置いてもいいわけではなく、あとで見た人が見失わない場所に置くことが重要です。

〇まとめ

今回のテーマである「やたら引数を増やす人は、なぜ増やすのか」の理由は、結論として変数を整理する能力が低いからということになります。
プログラマーは往々にしてプログラムを正しく動かすためにコードを書くという意識になりがちですが、これが間違いなのです。

コンピューターというのは本質的に情報を整理するためのツールなのですから、データを正しく整理することがコンピューターの根本目的であり、つまりプログラムの主役はロジックではなくデータが主役なのです。
プログラムはデータを正しく整理するためにコードを書くのであって、つまりデータを整理するためのガイドラインに過ぎません。

そういう意識が今までなかった人は、データを整理することを目的にコードを書いてみてください。
それが巧くできれば、今までよりワンランク上の綺麗な動作をするプログラムになると思います。

てなわけで今回はここまで。

〇次回予告

ところで、今回お話したようなことを、あらかじめ先輩から習っていた人はいるでしょうか。
多分ですけど、そういう人は世の中的に少数派だと思います。
今回のことを「当たり前のこと」と感じた人は、先輩から習ったのではなく、自主的に勉強して自分で気づいた人が大半ではないでしょうか。

なんでそう思うのかってぇと、今のIT業界では「先輩から知恵を受け継ぐ重要性」が軽視されがちだからです。
先輩は後輩に、教えなくてもどこかで自然に学んでくることを期待しているもののです。
私の場合もあまり運には恵まれず、若い頃は「教えてあげればすぐだけど、でもあえて教えない」という先輩の方が、何でも教えてくれる人よりも多かったように記憶しています。

なんで今のIT業界は、そういう人があふれてしまったのか。
次回はその話をしたいと思います。

Z世代と昭和世代との間には「学習コスト」というものに絶対的な意識の隔絶があって、これがもう修復不可能な状態である、という話。
楽しみにしていただけると嬉しいです。


この記事が気に入ったらサポートをしてみませんか?