多くの異なるファイルがあるプロジェクトを扱うとき、私は常に、パーツが相互にどのように相互作用するかを追跡できなくなっているようです。小さなコンポーネントを個別に理解するのにそれほど問題はありませんでしたが、プロジェクトの複雑さが増すにつれ、何が起こっているのかを精神的に理解することができなくなりました。メソッドとソースファイルの数が増えるにつれて、特にOOPプロジェクトでこれに気づきました。
私の経歴:私は独学のWebプログラマーです。私は主にpythonをすばやくダーティなスクリプト用に扱いましたが、いくつかの基本的な Django プロジェクトも行いました。Webフレームワークが好きです。 flask のように、単一ファイルレイアウトのシンプルさで、何が起こっているのか(ほとんど)を簡単に追跡できます。
私は今、他の誰かが開発した大規模なZend Framework PHPプロジェクトとやり取りする必要がある状況にあり、多数のファイルに広がるコードを理解しようとすることに圧倒されています。
他の誰かが開発した大規模なコードベースを理解するのに役立つテクニックとプロセスは何ですか?全体像を把握するのに役立つ特定の図はありますか?
大きなコードベースを理解するコツは、すべてを理解しようとしないことです。ある程度の大きさになると、全体の頭の中にメンタルモデルを置くことができなくなります。最初に作業する必要のあるすべてのタスクに意味のあるアンカーポイントから開始し、そこから分岐して、必要な部分のみを学習し、残りの部分がアドバタイズされたとおりに機能することを信頼します。再帰を理解するようなものです。スタック全体を頭に入れようとすると、脳が爆発します。
Grep、デバッガー、インテリセンスは、ここでの友達です。関数がどのように呼び出されるかわからない場合は、その関数にブレークポイントを設定し、スタックトレースをたどります。
もう1つ注意すべき点は、大規模なコードベースが突然生まれることはないということです。大きければ大きいほど、経験のあるプログラマーが増えるので、どこから始めればよいか具体的に説明してください。 「新しい支払いプロバイダーを追加する必要があります。コードのどこを探したらいいですか?」のような質問をします。コードベース全体を理解しようとするのではなく、そのタスクだけに集中してください。少しずつ親しみが深まります。
近道はありません。あなたはただそれに苦しむ必要があります。
図の取得方法に関する質問に答えるには、 doxygen が必要です。 AFAIKはPHPで動作します。
より一般的には、新しいコードベースに遭遇したとき、おおまかに次の段階を経ます。
ユーザーの視点からそれが何をするかを理解します。パワーユーザーのように自分で実際にアプリケーションを使用できるようにします。実際のエンドユーザーがそれをどのように扱うかを理解します。これには、彼らが何をしているかについてしっかりと理解するまで、彼らと一緒に座ることが必要になる場合があります。
可能であれば、元の開発者と連絡を取ってください。最初に、エンドユーザーエクスペリエンスによって刺激されるアーキテクチャの質問があります。後で、エッジケースと詳細についての実装に関する質問があります。開発者から回答を得ることができることは、コメントやドキュメントよりもはるかに役立ちます(これは、せいぜい不完全であり、誤解を招く、または完全に欠落していることがあります)。
使用しているフレームワークについて学びます。少なくとも、本番アプリケーションに飛び込む前に、そのフレームワークを使用して「hello world」またはその他の単純なアプリケーションを作成できる必要があります。
展開プロセス全体を把握します(元の開発者が手を握っているときに行うのが最適です)。現在のコードベースを取得してビルドおよびテスト/検証/製品環境でデプロイできない場合は、トーストです。小さな変更でも、展開のすべてのフープを一気に通過する必要があるので、この部分をすぐに下げてみませんか?そうすることで、アプリで使用されるすべての素敵なサーバー、データベース、サービス、スクリプトが紹介されます。「どこにあるか」がわかります。
機能テスト(ある場合)を把握します。正常に動作しているかどうかはどのようにしてわかりますか?アプリケーションの管理と供給のために、ユーザーは何をしなければなりませんか?
アプリのログを理解します。私はPHPで作業したことがありませんが、私はワイルドな推測をして、深刻なPHPアプリケーションには何らかのタイプのロギングがあると思います。ログを理解すれば、問題をデバッグする時が来たときの良い出発点です。
----ここまでは、コードベースを詳しく調べたことについては触れていません。 LOTがあり、コードを見なくても大規模なプロジェクトについて学ぶことができます。もちろん、ある時点で、コードに慣れる必要があります。これが私を助けるものです:
図の場合、 doxygen は、コールグラフやその他の関係を生成する優れたツールです。たまたまPHP=機能があります!doxygenを試していない場合は、絶対に試してみてください。フレームワーク内のコードがどれほどわかりやすいかは保証できませんが、しかしそれは役立つかもしれません。元の開発者は、コードのdoxygenで生成されたドキュメントを提示されたときに彼らが目にするものにしばしばショックを受けます。良いニュースは、彼らの記憶を揺さぶってあなたをより良く助けるのに本当に役立つということです。
単体テストのスイートがある場合、それらを詳しく見ると、アプリケーションの内部動作を確認できます。これらは、変更中に導入した可能性のあるバグを探す最初の場所にもなります。
IDEブックマークは、コードベースのホットスポットにタグを付けるのに非常に役立ちます。それらをすばやく切り替えることができると、理解が促進されます。
最近のバグレポートとその解決策を読むことは、ホットスポットを理解するのにも役立ち、コードベースの最も関連性の高い部分を理解するのに役立ちます。
リクエストに応じて、ここに回答としての私のコメントがあります。
他の人のコードを使用する場合、静的構造の概要を示すために、UMLクラス図を作成するか、可能であれば生成する傾向があります。特に後で戻る必要があり、クラスのコンテキストを忘れてしまった場合に、視覚的な図が役立ちます。私は時々、動的な振る舞いのためにそれを行って、共同作業者間の相互作用を明確にしますが、私はそれをしませんthatは頻繁に行いません。
コードベースにテスト(統合またはユニット)が含まれている場合、それらもチェックアウトする価値がある場合があります。
私は実際に、今週中に新しいクライアントが別の開発者が残した製品の機能強化を必要とする間にこれを開始します。以下は従うべきステップです:
a)使用されているプログラミングフレームワークを特定します。これは、アプリケーションのフローを知るのに役立ちます。
b)一般的なサービス-ロギング、例外処理、MVC、データベース接続、監査、ビュー(ページ生成)を特定します。これらは、私たちが最もよく使用する部分だからです。
c)(アプリケーション内の)共通のユーザーフローを実行し、コードのレイアウト方法に合わせます。
d)いくつかの変更を加えて、どのように表示されるかを確認します。変更を開始するまで、コードはまだブラックボックスなので、これが最大のステップです。
今後2週間の間に得られる他のアイデアをお知らせします
私の考えでは、ドキュメントを読む必要があります。私はハッカーがあなたに「コードはドキュメントである」と言って、ドキュメントを書かない言い訳としてそれを使うのを好むのを知っていますが、彼らは間違っています。何百万行ものコードからなる大規模なソフトウェアプロジェクトであるLinuxカーネルを見てください。本を読んで、それを手に取らなくては、誰もが真っ先にやって来るとは思えません。使用しているコードが文書化されていない場合(またはプロジェクトが小さい場合は十分にコメントされていない場合)、おそらく適切なコードではありません。
ドキュメンテーションがゼロの非常に大きなもので作業している場合(私も行ったことがあるので、それはおおざっぱです!)、私が見つけたのは、作業している部分を分離することです。コードのその部分で、データ/イベント/メッセージ/相互作用がそのユニットとの間でどのようにやり取りされるかを理解します。つまり、インターフェイスをリバースエンジニアリングします。それを書き留め。次に別のユニットで作業するとき(最初に作業したユニットと通信した場合のボーナス)、同じことを行います。すべてのドキュメントを保管してください。この数か月後、物事がどのように流れるかについての素敵な写真が得られます。
作業している1つの小さなユニットのインターフェースを見つけ、後で参照できるように記録します。時間が経つにつれて、それがどのように機能するかのほとんどを一緒にステッチします。プログラムの動作を見つけ、そのメッセージがどのように流れるかを追跡します。たとえば、システムが何らかの入力ネットワークメッセージを受け取り、出力メッセージを送信する場合、そのメッセージがシステムをどのように流れるかを追跡します。詳細について心配する必要はありません。どこに行くかを確認してください。
私がすることは、JavaからUMLに逆にされたすべてのファイルから単一のUMLモデルを作成することです。このアプローチは、モデルがプロジェクトの抽象的なビューではなく、プロジェクトだけであることを意味しますそれ自体は完全にMOFにマップされているため、UMLにマッピングされています。
私が得られるのは、分類子などで構成されたパッケージでそれぞれ構成された複数のサブモデルで構成された大きな単一モデルです。マルチプロジェクトレベルで作業すると、マルチプロジェクトレベルで各分類子とメソッド呼び出しをトレースできます。つまり、同じメソッドがプロジェクトAの1つの分類子とプロジェクトBの別の分類子を呼び出すことができます。プロジェクトの完全な構造を確認する唯一の方法は、両方を同時に逆にすることです。コンポーネント図を作成する時間がないので、情報は正確ではありません。私はコンピュータにプロジェクト全体を取り消すように依頼することを好みます。私はチームで各反復で逆を行い、すべての私の図はすぐに更新されます。リバースエンジニアリングはインクリメンタルであり、JavaからUML Idsへのマッピングを使用します。つまり、各Java要素は、単一の一意のMOF要素にマップされ、リファクタリングされても、プロジェクトの全期間を通じて同じです。これを行うと、UMLモデリングに制限がなくなり、非常に大規模で複雑なプロジェクトモデリングが可能になります。情報として、5 000 000行を超えるOOPコード。すべてのプロジェクトが正しく反転され、グラフィカルなナビゲーションが可能です
UMLモデルから常に最新のビューを必要なだけ作成できるため、私はクラス図のみを使用しています。非常に複雑なプロジェクトもモデル化できます。