大規模なコードベースがすでに配置されている既存のチームに参加することは、気が遠くなる可能性があります。最善のアプローチは何ですか。
私は現在約2万行のC++アプリとライブラリに取り組んでいます(編集:物事の壮大な計画では小さいです!)。業界では、経験豊富なプログラマーによる紹介を受けると思います。しかし、そうでない場合は、できるだけ早く付加価値を開始するために何ができるでしょうか。
-
回答の概要:
この投稿は 継承されたコードベースを使用して自分自身を理解するための最良の方法の部分的な複製です
可能であれば、いくつかの小さなタスクから始めて、問題の周りのコードをデバッグします。デバッグモードでコードをステップスルーするのが、何かがどのように機能するかを学ぶ最も簡単な方法です。
もう1つのオプションは、関心のある機能のテストを作成することです。テストハーネスを設定することは、システムの依存関係とその状態が存在する場所を確立するための良い方法です。各テストは、システムが機能する必要があると考える方法についてのアサーションから始まります。そのように機能することが判明した場合、あなたは何かを達成し、それを再現するためのいくつかの実用的なサンプルコードを持っています。それがそのように機能しない場合は、解決するパズルと従うべき一連の質問があります。
まだ言及されていない人々に私が通常提案することの1つは、開発者になる前に、既存のコードベースの有能なユーザーになることが重要であるということです。新しい開発者が私たちの大規模なソフトウェアプロジェクトに参加するときは、コードに取り組む前に、エキスパートユーザーになるために時間を費やすことをお勧めします。
当たり前のことかもしれませんが、多くの人が進歩を始めたいと思っているので、コードにすぐに飛び込もうとしているのを見てきました。
これは、あなたがどのような学習者であり、どのようなプログラマーであるかに大きく依存しますが、次のようになります。
厳密な回転でペアリングします。
可能であれば、ドキュメント/コードベースを確認しながら、厳密なローテーションでペアリングを採用するようにしてください。つまり、2人が一定期間(たとえば2時間のセッション)一緒に座ってからペアを切り替えると、1人はそのタスクに取り組み続け、もう1人は別のパートナーと別のタスクに移動します。
ペアで両方の知識を習得し、ローテーションが発生したときにチームの他のメンバーに提供することができます。これの良い点は、新しいペアがまとめられると、タスクに取り組んだ人(この場合はコードを調査する)が概念をより簡単に理解できる方法で要約して説明できることです。時間の経過とともに、誰もが同じレベルの理解を得る必要があり、うまくいけば、「ああ、ジョンだけがコードのそのビットを知っている」症候群を回避する必要があります。
あなたのシナリオについて私が言えることから、これには十分な数(3ペア)がありますが、分散している場合、または同じタイムスケールで作業していない場合、それが可能になる可能性はほとんどありません。
その上でDoxygenを実行して最新のクラス図を取得してから、しばらくの間広めることをお勧めします。これにより、コードに近づいて汚れたときに使用できる全体像がわかりやすくなります。
私はそれがあなたがどんなタイプの学習者であるかに完全に依存することに同意します。そうは言っても、私は最初から非常に大きなコードベースを持っていた2つの会社にいました。通常、私は次のように動作します。
可能であれば、関数型コードを調べる前に、すでに作成されている単体テストを実行します。これらは一般的に非常に役立ちます。それらが利用できない場合、私は次のことを行います。
まず、実装をほとんど無視し、ヘッダーファイルのみ、またはクラスインターフェイスのみを調べます。各クラスの目的が何であるかを理解しようとしています。次に、最も重要と思われる領域から始めて、実装を1レベル深く掘り下げます。これを測定するのは難しいので、時々私はファイルリストの一番上から始めて下に向かって進んでいきます。私はこれを幅優先学習と呼んでいます。この最初のステップの後、私は通常、残りのコードを詳細に調べます。最初の幅優先探索は、インターフェイスレベルから得たアイデアを固め/修正するのに役立ちます。次に、深さ方向の外観は、システムの実装に使用されたパターンと、さまざまな設計アイデアを示します。深さ優先とは、基本的にデバッガーを使用してプログラムをステップ実行し、各関数にステップインしてその動作を確認することなどを意味します。これは明らかに大規模なシステムでは不可能ですが、20kLOCはそれほど多くありません。 :)
システムに精通している別のプログラマーと協力して、新しい機能を開発したり、バグを修正したりします。これは私が見た中で最もうまくいく方法です。
これを特定のタスクに結び付ける必要があると思います。時間があるときは、気分に合ったアプローチを選んでください。
やらなければならないことがあるときは、自分自身に焦点を絞り、それを成し遂げてください。
まず、コードの経験があるチームメンバーがいる場合は、コードの概要を説明するように手配する必要があります。各チームメンバーは、専門分野に関する情報を提供する必要があります。複数の人に説明してもらうことは通常価値があります。なぜなら、他の人よりも説明が上手な人もいれば、他の人よりも理解が上手な人もいるからです。
次に、プレッシャーなしでしばらくの間コードを読み始める必要があります(上司がそれを提供する場合は数日または1週間)。多くの場合、プロジェクトを自分でコンパイル/ビルドし、プロジェクトをデバッグモードで実行できるため、コードをステップ実行できます。次に、足を濡らし、小さなバグを修正し、小さな機能強化を行います。すぐに中規模のプロジェクト、そして後で大きなプロジェクトの準備が整うことを願っています。あなたが行くにつれてあなたのチームメイトに頼り続けてください-しばしばあなたはあなたを指導してくれる人を特に見つけることができます。
あなたが苦労している場合でも、自分自身に過度の負担をかけないでください-それは正常です。大規模なコードベースを理解するには、長い時間、場合によっては数年かかることがあります。実際、何年経っても、コードの一部がまだ少し怖くて不透明な場合がよくあります。プロジェクト間でダウンタイムが発生すると、それらの領域を掘り下げることができ、数回試行した後でもそれらの部分を理解できることがよくあります。
幸運を!
私も同じような状況でした。私はあなたがこのように行くと思います:
これにより、システムに慣れることができます。単体テストを記述または理解しようとすることは、whatがテストされており、whyでテストする必要があることをよく知っている場合にのみ可能であることを忘れないでくださいonly =そのように。
また、データベースを対象としない大規模なアプリケーションの場合は、別のアプローチをお勧めします。
最初の戦略の場合: たとえば、このstackoverflowサイトの例を見てみましょう。データストア、何が保存されているか、どのように保存されているか、それらのアイテムがコード内でどのように表現されているか、UIのどこに表示されているかを調べます。それらはどこから来て、データストアに戻った後にどのような処理が行われるのか。
2つ目は ワードプロセッサの例を見てみましょう。どのようなコンポーネントがありますか? IO、UI、ページなど。これらはどのように相互作用していますか?さらに学習しながら進んでください。
安心する。書かれたコードは誰かの考え方であり、論理と思考スタイルを凍結し、その考え方を読むには時間がかかります。
チームに2週間(2週間ある場合)バグ修正を依頼してください。彼らは誰かにその責任を負わせて喜んでくれるでしょう、そしてその期間の終わりまでにあなたはおそらくそれをかなりよく知っているであろうライブラリで問題解決に多くの時間を費やしたでしょう。
ユニットテストがある場合(私はそうではないと思います)。小さく始めて、ユニットテストが失敗しないことを確認してください。コードベース全体を一度に見つめると、目が釉薬になり、圧倒されます。
単体テストがない場合は、必要な機能に焦点を当てる必要があります。アプリを実行して、機能が影響するはずの結果を確認します。次に、アプリが変更したいものをどのように作成するかを理解するために、コードを調べ始めます。最後にそれを変更し、結果が希望どおりに表示されることを確認します。
あなたはそれがアプリとライブラリだと言いました。まずアプリを変更し、ライブラリをユーザーとして使用することに固執します。次に、ライブラリを学習した後、変更するのが簡単になります。
トップダウンアプローチから、アプリにはおそらくすべてのアクションを制御するメインループまたはメインGUIがあります。アプリケーションの主な制御フローを理解することは価値があります。アプリのメインフローの概要を理解するために、コードを読む価値があります。 GUIアプリの場合は、どの画面があるか、ある画面から別の画面に移動する方法を示す紙を作成します。コマンドラインアプリの場合、処理方法。
企業でも、このアプローチを採用することは珍しくありません。多くの場合、アプリケーションがどのように機能するかを完全に理解している人は誰もいません。そして、人々はあなたを案内する時間がありません。彼らは特定の事柄についての特定の質問を好むので、あなたは自分で掘り下げて実験しなければなりません。次に、特定の質問を受け取ったら、アプリケーションのその部分の知識のソースを分離して質問することができます。
「問題ドメイン」を理解することから始めます(それは給与システムですか?在庫ですか?リアルタイム制御など)。ユーザーが使用する専門用語を理解していないと、コードを理解できません。
次に、オブジェクトモデルを見てください。ダイアグラムがすでに存在する場合や、ダイアグラムをリバースエンジニアリングする必要がある場合があります(手動で、またはDougが提案するツールを使用して)。この段階で、データベース(存在する場合)を調査することもできます。オブジェクトモデルに従う必要があるが、従わない場合もあります。これを知っておくことが重要です。
変更履歴またはバグデータベースを確認してください。頻繁に発生する領域がある場合は、最初にそのビットを調べてください。これは、それがひどく書かれているという意味ではありませんが、それは誰もが使用するビットです。
最後に、いくつかのメモを保管してください(私はウィキが好きです)。
Doxygenのようなツールを使用してクラス図を取得し、最初に全体像を理解する必要があるというすべての回答が好きです。私はこれに完全に同意します。
とは言うものの、これはコードが最初にどれだけうまく因数分解されているかに大きく依存します。それが巨大な混乱であるならば、それは学ぶのが難しいでしょう。きれいで、適切に整理されていれば、それほど悪くはないはずです。
テストカバレッジツールを使用して、その機能がどこにあるか、またはそれが多くのモジュールにどのように分散しているかについて何も知らずに、関心のある機能のコードを見つける方法については、 この回答 を参照してください。
コードに飛び込むだけでも少し圧倒されるかもしれません。設計に関するドキュメントをできるだけ多く読むようにしてください。これにより、各コンポーネントの目的と構造が説明されることを願っています。既存の開発者がそれを理解できるのであれば最善ですが、それが常に可能であるとは限りません。
コードの高レベルの構造に慣れたら、バグを1つか2つ修正してみてください。これは、実際のコードを理解するのに役立ちます。
(今後の恥知らずなマーケティング)
nWire をチェックアウトする必要があります。これは、大規模なコードベースをナビゲートおよび視覚化するためのEclipseプラグインです。多くのお客様は、主要なフローの視覚化を印刷することにより、新しい開発者に侵入するためにそれを使用しています。