記述していないコードを理解するために何をしますか?または、あなたがずっと前に書いたコードで、それが何をするかもう覚えていません。
あなたが行っているいくつかのテクニックはありますか?最初に構造を分析しますか、それともパブリックメソッドを分析しますか、それともフローチャートなどを描きますか?または、デバッガを起動して、ステップ実行するだけですか?それとも、理解するまで臨機応変に進んでいますか?
私は以下の組み合わせを使用します:
必ずしもこの順序である必要はありません:-)なんらかのリファクタリングの後にコードの一部が何をするかを理解するのがどれほど簡単になるかは驚くべきことです。
リファクタリング
コードを明確にし、標準でah-hockによって確立されたコード。
通常、最初に単純なパーツを分析します。小さなテーブルを維持するために使用されるモジュール。これは、他のプログラマが使用しているスタイルを教えてくれます。それでも理解できない場合は、書き方が非常に悪いか、言語やフレームワークなどの知識が不足しています。簡単な部分を理解したら、プログラムのより複雑な部分に移ります。
バグを修正してみてください
コードを知る最良の方法! :)
ユースケースを確認します。各ユースケースはある時点で始まり、別の時点で終わります。初めから見て、流れに従ってください。 3つまたは4つのユースケースを調べると、コードの構造がわかります。
コードを1行ずつ読み取るよりも、コードの調査においてより積極的な役割を維持するのに役立つため、コードをフォローするときにテストを作成することをお勧めします。
デバッガーはフローを追跡するための優れたツールです。実際には何もアサートしない簡単なテストをいくつか行うことができますが、デバッグするポイントからコードを開始して、デバッガーのクイックスタートポイントを取得できます。
テストの快適さにもよりますが、期待される結果を確認するにはテストの方が速い場合があります。
コールグラフを生成/描画/読み取り。
これは経験とともに来ます。あなたが初心者のとき、または他のプログラミング言語に飛び込むときは少し難しいです。言語を使って数年働いていると、理解しやすくなります。
しかし、原則として、デバッガーを起動して、デバッガーで何が起こっているのかを理解し始めます。また、コードにコメントを付け、文書化されたコードで作業することも非常に重要です。
良い質問です。私がこれまで座ってプロセスを文書化したことはないと思います。
私は今それについて考えていると思います、私はただそれを読みました:
行ごと
もちろん、これが常にうまくいくとは限りません。作者に尋ねることは通常、最後の手段です。
ホワイトボードを使用して、クラスまたはメソッド間の相互作用を記述および図化します。これは、プログラムのフローを確認するのに役立ちます。 100フィートのビューが表示されたら、システムのニュアンスを見つけるために、掘り出し、トレース、デバッグを開始します。
他のコードを理解するにはどうすればよいですか?
さて、ほとんど私はそれについて全く取りません。私はそれがうまくいかない場合にのみそれを理解しようとします、そして私が何か間違ったことをしたのか「他の人がしたのか」を理解しようとしています。そして、そのために使用するツールは、コードの読み取りとデバッガーの使用です。
それでも解決しない場合は、著者にメールを送ります。
学習スタイルは人によって異なるため、最適な方法を選択する必要があります。
(プロジェクトのビルド後に)最初に行うことは、コードベース全体を少なくとも1回は読み取ることです。それは私にすべてがどこにあるかについての一般的な考えを与えます。次に、セクションを選択してさらに詳しく調べます。まずはデータ構造から始めるのがよいでしょう。何が起こっているのかを大まかに把握したら、最初のコードと相互作用するコードの別の部分についても同じことを行います。十分な反復の後、コードがどのように機能するかをよく理解しています。
コードをどのように記述し、類似点を探すかを想像します。
クラスを読んでいるときは、そのクラスが持つ属性と動作(メソッド+フィールド)を見てください。メソッドの場合、メソッド名、入力パラメーター、および戻り値の型を覚えておいてください。メソッド名がわからない場合(難読化されているため)、場合によっては、入力、出力、および実装を調べることでこの情報を取得できます。
例として、この部分的に難読化されたメソッドを見てみましょう。
_public double f(double d0, double d1, double d2)
{
double d3 = this.locX - d0;
double d4 = this.locY - d1;
double d5 = this.locZ - d2;
return MathHelper.sqrt(d3 * d3 + d4 * d4 + d5 * d5);
}
_
これは3つのdoubleを受け入れ、doubleを返しますが、わかりやすい部分は数学方程式です。
ここで、f()
をdistance()
にリファクタリングする必要があります。簡単なものを最初にDecypherします。パズルをどんどん解くと、解読が難しい領域のヒントが得られます。
私のお気に入りのトリックは、control + Fです。それが検索機能です。また、を使用して、プロジェクト全体(個別のファイルだけでなく)を検索することもできます。何を検索すればいいのか、どうやって知るのですか?まあ、なんらかの方法でアプリケーションまたはライブラリを使用することで...何を検索するかについてのヒントが得られます。まず、あなたが探したい特定の機能の一般的なアイデアを持っています。次に、プロジェクトをほんの少しでも使用した場合は、より具体的な手掛かりを取得して検索を絞り込むことができます。
たとえば、非アクティブな作成者(418ファイルと46k行のコードを含むオープンソースのMinecraftプラグイン)から継承したプロジェクトに取り組んでいます。そして、ユーザーにチケットを開いてもらいました。「結合サインを使用するための許可ノードは何ですか?」一体、私にはわからない。そして、ドキュメントはそれについても触れていませんでした。汗をかくな、コントロール+ Fで救出(私の選択した武器)。
常に100%のデサイファーであるとは限らないことの1つは、彼らの質問ですdesign:「なぜ彼らはこのように設計したのですか?」推測することしかできない。
興味深い質問ですが、これまでにプロセスを文書化したことはないと思いますが、ここで私がやりたいことがいくつかあります。
査定
grep -l [text to find] [files to look in]
は、MacやLinuxでこの種のものに適しています。これがWindowsでどのように実現されるかはわかりません。
研究
それは私が受け継いだ内部プロジェクトであるという例をとります-多分私が一度も会ったことのない長い離れた同僚からかもしれません:
手動労働
これまでの手順はすべて、他者のコードのリバースエンジニアリングに本質的に関与する手作業の多大な量に備えるために設計されました。これまで、ほとんどの仕事は読書に集中してきました。
実質的なリファクタリングは、コードシステムの状態が実際にそれを必要とする場合にのみ実行する必要があります(つまり、実行が非常に遅くなり、 " 泥の大きなボール "などになります)。 1つのバグを新しいバグと交換する。私の経験では、プロジェクトをリファクタリングするだけでプロジェクトをリファクタリングすると、予期せぬ結果が生じます。これらの結果は、かなり後になって初めて明らかになる可能性があります。自動化された単体テストを使用しても、大規模なシステムでは、開発サイクルのすべての側面を再テストすることが困難な場合があります。