「短く分けて書くべき」でしょ?当然!!

…って、声が聞こえてきそうです。

本当に全ての場合に、そう言えるのでしょうか?


 “Without chaos, there is no creativity.”

8CC07FF3-3CEC-4E08-93C6-29C42DDCC4F4.png 4.77 MB

この考察は、下記のブログ内で感じたことを元にしています。読まなくても大丈夫ですが、読んでいただけると嬉しいです✨



上記ブログ内でプログラミングを学ぶ人に誤解をして欲しくないことがあります。

それが、何かというと…

「どうせリファクタリングして細かく機能ごとにプログラムソースのファイルを分けるなら、最初から分けておけば良いじゃん!」

…という考えです。
これ、危険な考え方です。
それが、何故かを説明したいと思います。

⚙️人間の思考は「連続的な流れ」の中で最も創造的になる🛠️

創造的な思考(Divergent Thinking、発散的思考)は、「脳が自由に連想しながら新しい発想を生み出すプロセス」 となります。つまり、アイデアは、ある種の「ひらめきの連鎖」のように発生します。そのため、一つのアイデアから次のアイデアへ連続的に考えることが創造性を生み出すのです。

この思考に逆らい、創造的な思考が必要なフェーズで、細かく機能ごとにファイルを整理しようとするとどうなるでしょう?
その整理の為に思考が中断され、創造の勢いが失われてしまう…という事が起こりうるのです。

特に、チャットモンスターのように、今まで誰も作った事のないアプリケーションは、何が正解か分からないため創造的な思考が必要となります。

⚙️人間の思考は「漸進的(ぜんしんてき)」に発展する🛠️

漸進的(ぜんしんてき)という耳慣れない言葉が出てきましたね。これは、物事を一気に完成させるのではなく、少しずつ段階的に進めていく という考え方になります。

人間の脳は「一気にすべてを理解する」ことが苦手です。そのため、物事を少しずつ試しながら、「理解しやすい単位」で進めていく ほうが効率的です。

漸進的なアプローチとは…

少しづつ試してみる    → 結果を見て調整する    → さらに改善する
 
というフィードバックループのような流れになります。
これは 実験的思考(Experimental Thinking)とも呼ばれ、人間が創造的に問題を解決する際の自然なプロセスなのです。

つまり、いきなり完璧なコードを書くのではなく、まずは動くものを作り、後から整理して改善する。こうした 「漸進的な改善」を行わず、最初から設計を完璧にしようとすると、逆に開発が進まなくなる という問題が発生してしまうのです。

 ⚙️「カオス(無秩序)」の中にこそ新しい発想が生まれる🛠️

心理学者エドワード・デ・ボーノの「水平思考(Lateral Thinking)」の理論によると、新しいアイデアは混沌(カオス)の中でこそ生まれるとされています。

人間の脳は、関連性のないものを結びつけることで「新しい発想」を生み出します。しかし、もし最初からすべてを「整然としたモジュール」に分けてしまうと、「既存の枠組みの中でしか発想できなくなる」という問題が生じます。つまり、最初から細かく分けると、自由な発想が制限されるため、ゼロから何かを作る際には「多少のカオスがあったほうが良い」という事になります。

これは「プログラミングの初期段階では、多少混沌としていたほうが創造性が発揮しやすい」という現象の説明となります。

⚙️「コードを分ければ分けるほど、読みやすくなる」 という誤解🛠️

プログラミングの学習段階では、「長いコードは悪」「短くして分けるのが正義」 という指導を受けることが多々あります。しかし、これをそのまま鵜呑みにし、コーディングのルールとして早期からこれを実践すると、非常に多くの問題が発生します。

早すぎる分割の最大の問題は、「コードの流れが分かりにくくなる」 ことになります。

早い段階から 「分けること」 を目的にしてしまうと、気づけば 大量の小さなファイル ができてしまいます。そして、ファイルがどこに何があるのか分からなくなります。
「あの関数ってどこにあるんだっけ?」 となり、grep検索の回数が増え、この関数はAとBの両方で使われているが、実際どっちに影響があるのか?」という 依存関係のカオス にも陥ることになるでしょう。

⚙️「早すぎる共通化」が引き起こす悲劇🛠️

ソースコードを短く分ける場合、処理を小さく切り出せる為、同じような処理をひとつに纏めよう…みたいな「共通化」を行うことが考えられます。
これが悲劇を生む事となります。

早い段階で「このコード、似てるから共通化しよう」と思い、まだ全体がボンヤリしているのに共通関数や共通モジュールを作る。しかし、後になって「実は少しずつ異なる仕様だった」ことが分かり、共通化されたコードが変更しづらくなるという現象が起こります。

つまり、「処理が似ているから共通化しよう」と思って共通化したとしても、実は似ているだけで本質的には異なることが多いのです。
それを共通化した場合、一旦個別処理に戻さないと、本当に共通化するべき部分が見えません。
その個別処理に戻す作業は「無意味な作業」に感じられるため、とてもやる気になれず、手がつけられないプログラムソースと成り果てます。

このことから、本当に共通化するべきだと判断できるまで、共通化しない…つまり、プログラムを短く分割しないほうが良いのです。

⚙️プログラムを短く分ける…リファクタリングの必要性🛠️

散々、プログラムを短く分ける弊害を説明してきましたが…プログラムはダラダラ長く書けばよく、短くしてファイル単位に分ける必要はないのでしょうか?

…それも違います。

心理学者ジョージ・ミラーの「マジックナンバー7±2」という法則では、人間が短期的に記憶できる情報の単位は 5〜9個 であるとされます。つまり、コードを理解するときも、ある程度の単位で情報が整理されていないと、人間の脳は負荷が増してしまうのです。

巨大なコードは一度に処理できる情報量を超えてしまうため、非常に負荷が高いといえます。特に、自分で書いていないプログラムソースを理解することは非常に難しいです。
それゆえに、最終的には、プログラムソースは適度に分けることが重要と言えるのです。

ここで重要なのは、「分割の基準は技術的な最適化ではなく、人間の認知の限界を考慮するべき」ということです。この認知的制約を無視して無闇に細分化すると、逆に混乱が増してしまいます。

つまり、リファクタリングの本質は、技術ではなく「人間の認知と行動の最適化」なのです。

⚙️リファクタリングの適切なタイミング🛠️

【プロトタイピング/創造的なフェーズ】
創造の段階では、細かいことを気にしないことが大切です。コードを書いているとき、「この関数は分けるべきか?」などと考えると、流れが止まります。まずは「大枠のロジック」を書いて、思考の流れを止めないことが大事です。
リファクタリングについては、考える段階ではありません。

【実装初期/MVP開発フェーズ】
MVP(Minimum Viable Product) とは、「最小限の機能で動く製品」 を指す概念です。
「試して動かす」→「少しずつ整理する」 を繰り返すフェーズとなり、「この部分はまとめたほうがいい」 という気づきを得たら、漸進的に整理・改善することもあります。ただ、リファクタリングを行うとしても最小限にするべきだと言えます。
発想を制限させない為にも「今は創造の時間」「今は整理の時間」を意識的に分けることも重要です。

【リファクタリング時期/機能追加フェーズ】
自由な発想でプログラミングを続けていくと、コードの複雑さが増し、開発速度が落ちてくようになります。
これは、技術的負債が積み上がっている状態と言えます。このように、「コードが変更しにくくなった」と感じたらリファクタリングのタイミングと言えます。
特に新機能を追加する前に、「変更しやすいコード」を作るために、リファクタリングを行うのが適切です。

以上のことから、チャットモンスターがなぜ2千7百行の一つファイルで作られているか?
なぜ、リファクタリングが必要なのかが理解出来たかと思います。

さて…ようやく次は「チャトモンリファクタリング/バージョンアップ」の【その2】ですね!

⚙️今後AIが自動ではやってくれないと思われる領域について🛠️

このブログに対しての@五月女 亮 さんへのコメントにお返事を書いたものの、少し分かりづらい表現になってしまったので、ChatGPTに書き直してもらいました。その結果、とても分かりやすく、良い感じのコメントの文章になったので、せっかくなので、ここに追記します。

リファクタリングの目的は、単なる可読性向上だけではなく、「これからどのように発展させるのか?」という視点が重要だと思います。その視点を持つと、そこには人間の意思が大きく関わるはずです。

チーム開発の場合、すでに確立されたテクニックやルールに沿ってコードが書かれるため、「他人から見た」可読性やメンテナンス性は、ある程度決まりきったものになります。しかし、ゼロから1人で新しいものを作る場合は、その枠にとらわれず、「自分にとって」可読性やメンテナンス性の高い設計を考える必要があります。

特に、どのような項目をオブジェクト化し、それをどのように拡張可能にするかは重要な判断の一つです。例えば、単一のデータだけを扱うのか、それをリストやマップのように複数同時に扱えるようにするのか、あるいは共通のインターフェースを持たせて拡張しやすくするのか、といった設計の選択肢があります。こうした判断は、将来的な機能追加や変更を見据えた上で、人間が意図を持って決めていく必要があります。

こうした構造の決定は、単にコードを整理するだけでなく、「世界観を形作る」ような作業になります。これは、単なる最適化ではなく、どのようにシステムを成長させるかを考えるクリエイティブな工程です。

最終的に、AIが完成したコードを読んで理解し、動作を把握することは可能になるかもしれません。しかし、どのようなオブジェクトを作り、どのように拡張するかといった「意思決定」の部分は、人間の創造力に依存するものであり、AIだけでは難しいのではないか? というのが私の考えです。