web-dev-qa-db-ja.com

他の誰かのコードに取り組む

私は1年ほどコーディングの経験がありません。作業を開始した後は、ほとんどの場合、他の誰かのコードに取り組み、既存の機能に新しい機能を追加するか、既存の機能を変更します。実際のコードを書いた人は私の会社ではもう働いていません。私は彼のコードを理解し、私の仕事をするのに苦労しています。コードを変更しようとしたときはいつでも、私は何らかの方法で機能を混乱させてきました。他の誰かのコードで作業している間、私は何を覚えておくべきですか?

60
Xavi Valero

コードには単体テストがありますか?そうでない場合、私は強くそれらを追加し始めることを提案します。このようにして、新しい機能/バグ修正を失敗したテストとして記述し、テストに合格したコードを変更できます。ビルドするコードが多いほど、追加したコードが他のものを壊していないという確信が高まります。

完全に理解していないコードの単体テストを作成すると、そのコードを理解するのに役立ちます。もちろん、機能テストがまだ存在しない場合は追加する必要があります。私の印象は、それらはOP質問からすでに存在していたということでした。その点で私が間違っている場合は、これらの機能テストが最初のステップになるはずです。

Eagle76dk 作成 大きなポイント この作業を行うために上司を任命することについて-Eagle76dkの投稿に詳細があります。

さらに、これらのテストを作成する際には、コードの動作ではなく、メソッドが達成しようとしたビジネスの動作を検証できるようにテストを作成することをお勧めします。また、コードに表示されるビジネス動作が正しいものであるとはまったく想定しないでください。アプリケーションが何をすべきかを教えてくれる誰かがいる場合、多くの場合、コードが示す内容よりも価値があります。

単体テストについて述べた別の答えに加えて、変更を簡単に元に戻すことができるように、すべてがバージョン管理されていることを確認することをお勧めします。そして、コードをより保守しやすくするために小さな変更を加えます。

46
Klee

私の意見では、他の誰かのコードを学習する最も速い方法(特に、変更が説明したように予期しない動作を引き起こす場合)はデバッガーを使用してコードをステップ実行することです。

プログラムのメインループ/メインメソッドのように見えるものをステップ実行することから始めます。 step intoおよびstep out関数を使用して、さまざまなメソッドの機能を確認します。これにより、コードの一般的な構造がわかります。

その後、より深いレベルでプログラムのさまざまな部分を段階的に学習して、分割して征服します。ほとんどのデバッガーでは、変数の調査現在の値を使用できます。それらがいつどのように変化するかを調べます。

懸念される動作をトリガーするメソッドにbreakpointsを設定します。たとえば、プログラムでテキストを変更しようとしていて、テキストが元の値に戻り続ける場合は、テキストが変更されたすべての場所にブレークポイントを設定するか、これらのすべての変更を1つのメソッドに移動してみてください。 call stackを使用して、このメソッドが呼び出される場所などを確認します。

コードの行を変更すると予期しない変更が他の場所で発生する場合は、その行にブレークポイントを設定し、スコープ内の現在の変数の値を確認し、step intoを使用するなどして、そこで何が起こるかを確認します。呼び出しがどこから来たかを確認するための呼び出しスタック。

これをたくさん行うことで、コードの構造を驚くほど速く学ぶことができます。私はあなたが私の最初のプログラミングの仕事をしたのと同じように、何年も前に書かれ、何年もかけて多くの人々によって変更された多くのコードを書き始めました。他の人々が同時にコードに取り組んでいるからといって、コードは私のものではありませんでした。その時点では、すべてを書き直すことはできませんでした。これらすべてのコードのテストを作成するには、数か月または数年かかります。デバッガは本当に私を救いました、私がそれなしでどのようにコードを学んだのか分かりません...

32
jake_hetfield

最初に覚えておかなければならないことは、コードの記述よりもコードの読み取りに多くの時間が費やされるということです。時間をかけて、他の男がどのように働いたか、彼のスタイルと問題へのアプローチを理解してください。

可能な限り既存のスタイルを採用するようにしてください。それ以外の場合は、2倍の調整が必要になります。

他の誰かのコードを扱うことは、例外ではなく標準です。他の人が問題を解決したり、機能を実装したりする方法を理解することに熟達する必要があります。これを実行すると、彼のコードを処理するのが簡単になります。

30
jmoreno

他の人のコードが悪臭を帯びていると思い込むのが早すぎないでください。

しかし、常に疑わしい。

しかし、そうです、別の開発者のコ​​ードを理解するには時間がかかります。関数またはオブジェクトがシステムの複数の部分で使用されるほど、注意が必要になります。症状により近い問題を解決できる場合は、それが役立つことがあります。たとえば、データが配信された後、何かが発生する前に、フェンスの問題オブジェクト側の別のオブジェクトからの受信データを正規化します。

あるものを変更すると別のものが突然壊れる場合、それは悪い兆候です。他に経験豊富な開発者がいて頼りになる場合は、問題の原因となっているものを見てもらうことをお勧めします。少なくとも、デバッグを監視しているものをいくつか取り上げることがあります。

21
Erik Reppen

理想的な世界では、特定の開発者が作成したすべてのコードは、文書化され、適切に構造化され、包括的にテストされます。ユニットテストなどの自動ツールと、ユーザーが実行して期待どおりの結果が得られるかどうかを確認するユースケーススクリプトを使用します。

しかし、あなたが最初に学ぶことは、私たちは理想的な世界に住んでいないということです!

多くの開発者はコードを適切に文書化していません。仮に、ビジネスロジックと無関係のコードを混在させており、彼らが行う唯一のテストは、通常のユースケースであると期待されることをすばやく実行することです。

このようなコードを使用する場合、最初に行うべきことは、それが何をするのかを確立することです。コメントがある場合、それらはあなたに手掛かりを与えるかもしれませんが、それを当てにしないでください。多くのコーダーは自分自身を説明するのが苦手で、たとえコメントを残しても意味がないかもしれないというのは私の経験です。ただし、あなたが会社で唯一のコーダーでない限り、誰かがコードの目的とそれが何をするのかについて少なくとも基本的な考えを持っているはずです。質問してください!

あなたがユニットテストを持っているなら、それらはあなたの人生をとても簡単にします。そうでない場合、コードベースの学習の一部には、すでに存在するコードの単体テストの記述が含まれる場合があります。通常、これは良い方法とは見なされません。既存のコードに適合するように単体テストを作成すると、コードはそのまま機能するものと見なされる単体テストが作成されるためです(実際にはバグである動作を想定して作成されます)正しい)、しかし少なくともそれはあなたにベースラインを与えます。後で正しいと思った動作が実際に間違っていることに気付いた場合は、ユニットテストを変更して、コードが現在提供している結果ではなく、期待される結果をテストできます。単体テストを作成したら、変更を加えて、加えた変更がどのような副作用をもたらすかを評価できます。

最後に、ドキュメントに記載されていないコードを処理する場合に最適なリソースは、エンドユーザーに尋ねることです。彼らはコードについて何も知らないかもしれませんが、彼らはアプリケーションが何をしたいかを知っています。要件の収集はどのプロジェクトでも最初の段階であり、開発されるシステムの見込みユーザーと話し合うことは常にその重要な部分です。たまたますでにビルドされたばかりの新しいプロジェクトの要件取得段階を実行していると考えてください。

よく書かれ、十分に文書化されたコードでさえ、部外者が理解するのは難しい場合があることを覚えておいてください。コードは本質的に、それを書いた人が当時考えていた方法の表現であり、誰もが独自の独自の思考プロセスを持っています。あなたは少し忍耐強くなり、探偵になることを学ぶ必要があります。他の人の思考プロセスに入り込むことは難しいですが、既存のコードのメンテナンスを行うプログラマにとって不可欠なスキルです。ほとんどのコーディング(約70%)は既存のコードの保守に関連しているため、学ぶことは重要なスキルです。

ああ、そして、十分に文書化されておらず、テストされておらず、ごちゃごちゃしたコードが引き起こす可能性のある痛みを見てきたので、次の貧しい開発者にそれをやってもらいませんよね? :)前任者の過ちから学び、コードをよくコメントし、すべてのモジュールが明確に責任を明確に定義していることを確認し、最初に(TDD方法論のために)記述する単体テストの包括的なセットがあることを確認します。少なくとも開発中のコードと並んで。

14
GordonM

作成していないコードを読み取る機能は非常に貴重なスキルであり、おそらくコードを作成するよりも価値があることを覚えておいてください。残念ながら、これは広く控えめで、学校ではあまり教えられていません。

私が言おうとしているのは、最初にコードを読んだときに常にコードを理解しているわけではないということです(完璧なコードを最初に作成しないのは普通のことです)。外部コードを取得するのに時間がかかることを受け入れる場合は、余分な労力を費やすことを気にしません。簡単な要約:

  • 単体テストは理想的ですが、必ずしも現実的ではありません。特に、官僚機構が重い大規模な組織で働いている場合はなおさらです。

  • バージョン管理システムを正しく使用する方法を学びます。あなたは既存のものを壊すことは決してありません(実際には決してではありませんが、それは良い安全策です)。

  • すぐに理解できないからといって、それが悪いと思い込まないでください。機能しているからといって、それが良いとは限りません。重要なことは、前のメンテナのコー​​ドスタイルを理解し、追加した行を彼のスタイルに適合させることです。あなたの後に来るメンテナに感謝します。

  • 一部の企業では、残念ながら、コードの読み取りの難しさを過小評価している場合があります。これは、厳格なプロセスを持つ大企業では一般的です。彼らはしばしば(暗黙のうちに)クリーンなものを書くのに時間をかけるよりも、素早く機能するPushコードを好むでしょう。この時点でチームがどこに立つかは、あなたに任せます。

  • 最後に、コードの読み取りはスキルであることを忘れないでください。やればやるほど、上手くなります。これを言い換えるもう1つの方法は、onlyを上手に使う方法は、何度も練習することです。上で述べたように、コードの読み取りは、書き込みよりもはるかに大きな役割を果たします。

13
rahmu

誤ってデータを壊してしまうという問題から判断すると、コードが自動テストの対象になっていないと想定します。ステップ#0は、Michael Feathersが レガシーコードを効果的に使用する をすぐに注文して読むことです。それは単に貴重です。

私が提案する基本的なステップ:

  • 現在の機能をカバーするテストでコードをカバーします。
  • 理解できるまでリファクタリングします。
  • 新しい機能または変更された機能のテストを記述します。
  • 新しい機能を実装します。
  • 満足するまでリファクタリングします。

私は意図的にテストの種類(ユニット、統合など)を指定しないでください-ある種の自動テストカバレッジを取得するだけです。

(そして、はい、レイアウトと命名の観点からコーディングスタイルに従ってください)

11
rjnilsson

前述のとおり、現実の世界へようこそ。私は以前の答えにのみ同意することができます。私は時間の見積もりに関する私の仕事の経験で答えを拡張したいと思います。

上司を明確にするための良い提案です。他の開発者の考え方を学ぶには時間がかかります。通常、あなたは現在の解決策がしばしば開発者の年齢と経験に依存することを経験するでしょう。

運が良ければ、手元のタスクを分析する必要があり、ドキュメントを理解することで大きな助けになります(ただし、多くの場合そうではありません)。

私の経験では、他のコードを変更するときは、現在のタスクに関係のないコードは変更しないようにしてください。あなたはより良い解決策を知っているかもしれませんし、それはより直感的な方法で書かれるかもしれませんが、それを変えることはしばしば次のような問題を引き起こします:

  • タスクには時間がかかり、上司はそれを理解しません。
  • 変更するコードはテストする必要があり、コストがかかります。現在のソリューションはテストされ、承認されています。
  • どの変更が現在のタスクを解決し、どれが「単なる」修正であるかを確認することは困難です。

しかし、何か違うと思うものを見つけたら、上司に言うのをためらわないでください(それはあなたが考えることができることを示すだけです)。

最後に、ソリューションを作成するのに十分な時間があることを確認してください。より高速なソリューションには経験が伴います。しかし、これがエラーやメンテナンス不可能なコードの最初の/主な理由であるため、めったに速い解決策はありません。

10
Eagle76dk

人に対する操作のようなものだと考えてください。

修正する必要のある問題を内部で確認すると、ほとんどの動脈などが、設定したとおりに設定されていないことに気づきます。そのため、適切に見えるまで切り取り、切り刻んで問題を修正します。

驚くべきことに、あなたの患者はほとんどすぐに死にます。

従来のアプリケーションも同じです。彼らはすでに作業方法を持っています-ソフトウェアのさまざまなコンポーネントとそれらが互いにどのように関連しているかを理解し、同じように機能するように変更を加える必要があります。創造性を発揮させるのはエキサイティングではありませんが、個人的なプロジェクトでそれを行うことができます。

シニアエンジニアに毎週月曜日に1時間ほど座ってもらい、システムのさまざまな側面について説明してもらいます。彼が言ったことをメモし、そのメモを彼とあなたのマネージャーにメールで送信して、マネージャーに追加するものがあるかどうかを確認します。あなたはこの方法でかなり速くスピードアップするべきです。

物事を壊さない方法については、まずシステムが何をしているのかを理解しておく必要があります。前にテスト-変更を加えて、後でテストします。魔法のような公式はありません。あなたが経験を積むにつれて、あなたはより良くなるでしょう-または私は解雇されるでしょう

5
Stefan

ここで触れたことのないもの-島で作業しないでください。

あなたがあなたの衣装で唯一のプログラマーでない限り、あなたよりも多くの経験を持つsomebody、そしておそらくあなたが傾けることができる多くの人々がいるはずですオン。

質問をする。それらの多くは。

(理由の範囲内で)誰かを「迷惑」にすることについて心配しないでください。通常の開発サイクルでは、後で本番環境で火を消さなければならないよりも、誰かが質問のために1つまたは2つの質問に割り込まれたほうがいいです。

何かをチェックインする準備ができたら、メンターに確認してください。彼らは何かが何か他のものを壊すかどうかだけでなく、より重要なことには、その理由を伝えることができるはずです。コードをレビューすることは、メンターをより優れたプログラマーにして、他の方法ではあまり見られないかもしれないシステムへの見方を与えます。

覚えておいてください。あなたは新入社員が必要とするシステムを学ぶだけでなく、プログラマーになる方法も学んでいます。

そして5年後、次のニューガイにあなたをメンターとして使うように勧めましょう。

3
Wonko the Sane

コードのデバッグに関しては、次の点に注意してください。常に理由があります。数日間同じ愚かなバグを見つけて修正しようとしていて、何の進歩もない場合、次の1つ以上を考え始めるのは魅力的です。

  • このコードがどのように機能するかを理解するのに十分なほど賢くない

  • このコードを書いた人は彼が何をしているのか全く分かりませんでした

  • 魔法が関与している:非常に黒い魔法

それらはすべてあきらめの形です。解毒剤はコンピュータが決定論的であることを常に覚えていることです:常に彼らがすることには理由があります。コードは魚の缶詰工場での干潮のようなにおいがし、巨大なリングイネのボウルに似ているかもしれませんが、執拗に合理的であり、心を開いておくことで、あなたはそれを理解します

2
Caleb

可能な場合は単体テストを作成する場合でも、変更するコードを含む小さなアプリケーションを作成する場合でも、ロジックを確認して理解し、文書化する必要があります。

コードがほとんど機能する場合-機能しているように聞こえますが-それはあなたのスタイルであるかどうかにかかわらず、そのモジュールのコードフォーマットのスタイルを保持します。それは物事を均一に保ちます。ただし、優れたコメントが時代遅れになることはありません。

本番環境を壊すことなく、このコードを変更およびテストできるテストシステムとテストプラットフォームをお勧めします。

ライブラリのコード要素を削除できる場合は、ライブラリで作業しているのでない限り、削除します。

時間が経つにつれて、ロジックを理解したら、書き換えてテストすることができます。

このアドバイスは、使用している言語、テストベッドを取得する機能、およびその他の制約によって左右されます。

1
octopusgrabbus

いくつかのコードアナライザーツールを使用して、削除できる未使用のコードを見つけてください。少なくとも、このコードについて心配する必要はありません。

1
FrVaBe

上記で、コードの詳細だけでなく、システムの目的を理解する必要があると述べました。注文入力システムを作成するのに十分な経験を持つプログラマーは、製品の選択、請求書のフォーマット、および支払いの処理を含む「前進」部分に一般的に慣れています。行き詰まるのは、ユーザーが「気にしない」と決定してトランザクションのバックアウトを開始したとき、または支払い処理でエラーを発生させて「戻る」ボタンを押したときです。その時点で、多くのプログラマーはコードが「どこからともなく現れる」のを見て、なぜそこにあるのか理解できないため、混乱します。

つまり、「通常のフロー」だけでなく、誰かがミスをしたり、気が変わった場合に必要なすべてのバックトラックを理解する必要があります。これは、一部のコードが特定のアカウント権限でのみ実行できるスーパーバイザオーバーライドでさらに悪化します。

誰かが年間10,000行のコードを記述し、アプリケーションの「ライフ」が10年である場合、他の誰かの作業をピックアップする責任を持つプログラマーは、100,000行のコードを理解する必要があります。これを1ページあたり50行で除算すると、2000ページになります。プログラムが設計パターンで記述されている場合、プログラマーは、1つの「ブロック」を理解することで、少なくとも残りのほとんどを一般的に理解できるようになります。そうでない場合は、最後の行をすべて読む必要があります。

一部のプログラマーは、「言われたことをただやって」スパゲッティを書いています。彼らが「全体像」を理解することは決してありません-彼らはユーザーが不平を言ったときに修正を加えるだけです。このような状況では、適切なパターンにできる限りの移行を開始することをお勧めします。結局、これは「壊れていない」ものを再コーディングすることを意味するかもしれません。心配する必要はありません。プロジェクトである限り、保守性が徐々に向上することを確認してください。

1
Meredith Poor

ここには本当にいい答えがいくつかあります。しかし、既存のコード(よく書かれたコード)を読み、読みやすいコードを書くために、優れた デザインパターン にどれほど精通しているのかについても言及する価値があると思います。

もちろん、既存のコードでSomethingFactoryに出会うと非常に混乱する可能性があり、実際には factory pattern に従いません。しかし、チームとフレームワークが許す限り、そのようなケースを最小限に抑えることは有益かもしれません。

(ビジネスニーズで許可されている)設計パターンに従うことで、コードの重複を大幅に減らすことができ、将来の変更時のバグを減らすことができます。

設計パターンに関するいくつかの良い情報源は

http://sourcemaking.com/design_patterns

http://www.oodesign.com/

そしてもちろん本

http://www.Amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612

0
Nameless One

メソッド間の制御の流れを追跡することは、ビジネスロジックのメンタルマップを開発する上で非常に重要です。

私たちのソリューションは、レガシーシステムにアプローチするときに利用できる数少ない信頼できる情報の1つが実行中のシステム自体であるという認識に基づいています。私たちのアプローチは、実行トレースを具体化し、ロジックプログラミングを使用してテストを表現します。

ワークフローデータモデルの生成は、すべてのコードパスを分析する最良の方法です。

実際には、コードレビューは、従来の科学ワークフローでは扱いにくくなります。このようなワークフローの起源は、ソフトウェアエンジニアリング手法が開発中に適用されなかった可能性があり、コードベースが事実上難読化されることを意味します。静的分析はデータフロー分析の技術を十分に開発してきましたが、実際のワークフローでの動作をサポートすることはできません。たとえば、データの処理方法を決定するために構成ファイルをロードする必要がある場合や、動的コード評価が使用される場合などです。

ワークフローを視覚化することが理想的です。

ビジュアル開発に役立つ共通のモチーフは、ワークフローをグラフとして表示することです。これは、リソースと実行の根本的な複雑さからユーザーを保護します

参照

0
Paul Sweatte