先日後輩に1on1で聞かれた時にすっと答えられなかったこの質問をふりかえってみる。
体系的な知識は本から学べるが...
確かに本を読めば体系的に学べる。
といった名著と呼ばれるような書籍はもちろん、最近であれば
といった比較的ハードルの低い書籍も増えてきた。
しかし、体系的な知識をインプットしても設計パターンや原則を実際のコードに落とし込むスキルにはならない。
「知識がある」と「実践できる」の間の溝
AIコーディングツールをそれなりに使っている人にはAIに「クリーンアーキテクチャで設計して」や「SOLID原則で実装して」などと投げてもろくな結果にならないのは周知の事実。
ではその机上の理論を実際の実践に落とし込んで、適切なタイミング、粒度、方法で適用できるようになるのに最短の方法は?というと端的に言えば「やってみるしかない」となるわけだけども、いきなり複雑な業務ドメインの中心となるようなコードを若手や新卒が書く、というのはまともな現場ではあまりないはず(だと思いたい)。
となると設計スキルを習得するには設計するしかないが、業務の中で設計をする経験を詰めるのは
- 現場がまともな状態ではない
- 先輩や上長にあたる人がタスクをアサインしてくれる
の2パターンくらいしかないのでは?という気がするし、2つめに関しても開発チームのリソースやリリース期限などの要因次第では若手の学習機会よりもビジネスチャンスが重視されてしまい、経験が積めないということもあるのではないだろうか?(そして1の場合は設計に対して適切なフィードバックが得られることは多分ないので、よほどの天才でなければ適切な設計を身につけることは難しいのではとも思う)
できるようになるにはやるしかないが、やるためにはできるようになる必要がある
これはソフトウェア設計に限ったことではない。
仕事が回ってくるようになるのは正常な企業であればその仕事を遂行できるようになってからだ。
しかし、これでは有名な兄弟喧嘩ミームのような状態になってしまう。
自分は上記の例でいうとどちらかというと後者寄りの機会の中で初期の頃の設計経験を積んだのだけど、
当時のことを思い返してみると、目の前の泥臭いコードをなんとかしようと夢中で色んなことを勉強していたし、その時は誰に言われるでもなく「もっといい方法があるはずだ」と勝手にやり方を探していた気がする。
今同じ質問を再度されたら
「目の前にあるレガシーコードを、ブランチをチェックアウトして徹底的にリファクタしてみれば?」
と答えるかもしれない。
(これはレガシーコード改善ガイドにも記述のある「試行リファクタリング」というプラクティス)
結局「養殖」されたコードでは業務で起こりがちな複雑な要件を再現することは難しいし、個人で開発できるレベルの単純なアプリケーションでは必要性を理解することも難しいだろう。
だからこそ、今目の前にある(かもしれない)複雑な業務要件と当時の環境やビジネス要求から生み出されたレガシーコードこそが最高の「教材」となりうるのではないだろうか?
少なくとも自分は手続き型で書かれ、ネストやループが数段になっているようなコードを「俺だったらこう書くのに」とか「この処理の引数と戻り値は何になるんだ?」などと言いながら処理をプライベートメソッドやクラスに抽出し、テストを書くことで、それまでインプットしてきた知識を、今自分がアプリケーションを作る時に使っているようなテクニックとして身につけた気がする。
そしてそういった知識の身体化に関しては、(少なくとも今現在は)AIが代わりにやってくれるようにはならないので、
- 複雑な業務要件を持っていて保守するべき既存資産があるような現場で
- AIの書くコードの正当性を評価できるようなエンジニアを目指すのであれば
一見回り道のようにみえるそういう泥臭いことをやってみてもいいのではないかと思う(生き馬の目を抜くようなスピードでAIエージェントが進歩している今の時代にそんなロートルなやり方をどこまで推奨するかは悩ましいところではあるが...)