はじめに
こんにちは、MasaKuです。
昨今、コロナウイルスの影響により、オフラインで開催される勉強会が自粛の流れになっており、逆にオンライン開催される勉強会が増えてきていると思います。
そこで先日、以下のイベントに参加しましたので、参加した感想について述べていきたいと思います。
参加したイベント
ドメイン駆動設計入門 ボトムアップでわかる!ドメイン駆動設計の基本 の著者 成瀬允宣さん主催のオンライン勉強会ということで、他人がどんな風にコードを読んでいくかを知ることを目的とした勉強会です。
今回は、PHP フレームワークの Laravel の内部を見ていこうという趣旨のコードリーディングでした。
なお、今回のフレームワーク読解の目標としては「自作フレームワークを作るために参考にする」という体で進められていました。
参加動機
そもそも、なぜ私がこの勉強会に参加しようと思ったのかをご説明しようと思います。
- ほかの人がどのようにしてコードを読んでいるのか単純に興味がある
- 人気のフレームワークの中身を読んでみたいけど、一人で読んでいると行き詰ってしまう
- フレームワークを読み進める上でのテクニックを吸収したい
- 定石パターンなどがあれば今後ソースの読み書きをする上でも参考になりそう
ちなみに、主催の成瀬さんについてですが、2019年のPHPerKaigiの際にアンカンファレンスにて発表されていた内容が非常に興味深かったことを覚えています。
そのことがきっかけでまたお話を伺いたいなと思ったことも動機の一つです。
(2019年のPHPerKaigi のイベントレポートは以下)
感想
コード理解はまず全容把握から
コードを追いかけるスピードはさることながら、コードを読むテクニックについても勉強させていただきました。
例えば、フレームワークの様な全容の大きいプログラムは、一度にすべてを丁寧に読み込んでいこうとするのではなく、まずは全体を眺めることが大事です。
「この変数にはどういう値が入っていて、どういうメソッドに渡されて、ここでオブジェクトに格納されているプロパティを取得して・・・」などということをすべて頭に入れながら読み進めていくと、間違いなくオーバーフローを起こして思考が停止してしまいます。
なので、まずはざっくりと全体の流れを把握して、それから、気になるところを読み返していく、という読み方が良いそうです。
この点に関しては、私も業務で開発しているプログラムを読み進めていく際に気を付けているポイントだったので、自分の進め方が大きく間違っていないことに安心しました。
いくつもの業務ロジックが関連するような処理を読み込んでいく際は、最初から細かに処理を追いかけるのではなく、ざっと処理の流れを把握してから細かい仕様を確認するようにしています。
全容がわかっていれば各処理の細かい仕様がなぜそうなっているのかも紐づけて考えやすいと思います。
図解はやはり強力
また、フレームワークの全容理解を進める上では、図解するのが一番良いと思いました。
Laravelにはリクエスト情報をコントローラに渡す前やViewに返す前に Middleware という処理を追加できます。
この仕様については把握していたのですが、何となく把握していたことを図解してもらえるだけで、Middleware がフレームワークのどのような位置でどのような処理をしてるのかが、より詳しく理解できたような気がしました。
自分の理解を振り返るためにも、図解しておくことは強力な理解促進につながると思います。
コードのわかりやすさも重要だがディレクトリ構造はもっと重要
フレームワークではアプリケーション開発で必要になる様々な処理を実現するために、各機能を適切な粒度でグルーピングしてディレクトリを切って管理しています。
配置するプログラムがきちんとグルーピングされたディレクトリに管理されていると、とある処理を追いかけていた際にたまたま見つけた特定処理に関連するパーツがどこで管理されているかも分かりやすくなります。
もちろん、コード内からジャンプして、参照元へどんどんたどっていくこともできますが、関連する処理がどこにあるのかがわかっていると、リファレンスを読まなくてもフレームワークが行っているその他の処理を知るきっかけにもなります。
逆に、ディレクトリ構成が支離滅裂でどこに何が配置されているのかがわかりにくい状態になっていると処理を追いかける際の可読性を下げてしまうばかりでなく、管理も煩雑になってしまって保守性も低下してしまうでしょう。
PHPのマジックメソッドはコードリーディングにおいてかなり曲者になる
中でも__call()
や __callStatic()
はコードリーディングを難解にさせるマジックメソッドの一つです。
例えば __callStatic()
は、オブジェクト内の静的メソッドを呼び出そうとする際に、アクセス不能な場合に実行されるメソッドです。
<?php // 以下サンプルコード class MagicMethodTest { public static function __callStatic($name, $arguments) { echo "あなたが呼び出したメソッドは '$name' " . implode(', ', $arguments). "\n"; } } MagicMethodTest::runMethod('引数1','引数2'); // 実行結果 // あたなが呼び出したメソッドは 'runMethod' 引数1, 引数2
フレームワークではこうしたメソッドが頻繁に登場するようなのですが、普段のアプリケーション開発時はあまり目にする機会が少ないだけに、一瞬思考が止まっていしまいます。
しかし、主催者の方や参加者の方々と、まるでペアプロしているかのように読み進めていくことで、マジックメソッドの意味を冷静に考えながら読み進めていくことができます。
参加者のコメントもインプットになる
今回のイベントは YouTube Live で公開されていたため、他の参加者の方のコメントを読むこともできました。
コメントの中には自分と同じようなことを感じながらコードを読み進めている方がいらっしゃったり、別視点の深い内容のことをコメントされている方がいて、コードリーディングのモチベーションを高めながら参加することができました。 (参加者の中にはLaravelに非常にお詳しい方も参加されていたようで、鋭いコメントをされる方もいらっしゃいました。)
参加者間のコミュニケーションが活発であったことも非常に印象的で、終始途切れることなくコメントが流れていました。
おわりに
今回、オンラインのコードリーディングに参加させていただき、他の人がどのようにコードを読み進めているのかを拝見することができました。
フレームワークのような巨大なコードを読む上では、まずはざっと全容を把握してから、細かいポイントを振り返って理解しながら読み進めていくべきだと思いました。
振り返っていくときのポイントとして、とある処理で利用されるクラスには他にどのようなメソッドがあるのか、というところまで視野を広げることで、フレームワークが実現できる他の処理を知るきっかけにもなることを理解しました。
これらをスマートに進めるためにも、ディレクトリ構成をしっかりとルール付けして、正しく管理しておくことが重要です。
これらのノウハウは業務で開発しているプログラムを読み込む際にも使えるテクニックだと思いました。
例えば、ドツボにはまってしまって、同じところをグルグル読み返してしまう、なんてことが起きないようにするための方法として、いろいろと参考になることを得られたかなと思いました。
次回の開催も楽しみです!
なお、弊社ラクスでもオンラインでPHPの勉強会を開催しています。
LaravelについてもLTなどで過去に何度か話題になっていますので、ご参加いただけると幸いです。