12

私は中規模のチームで働いており、これらの非常に大きなクラス ファイルに定期的に遭遇します。私の最初の傾向はナイフで彼らに向かうことですが、それは通常、事態を悪化させ、私を悪い精神状態に陥らせます.

たとえば、作業する Windows サービスが与えられたとします。現在、このサービスにはバグがあり、それを修正する望みを持つ前に、サービスが何をするかを理解する必要があります. サービスを開くと、誰かがすべてに 1 つのファイルを使用することにしたことがわかります。そこには Start メソッド、Stop メソッド、タイマー、すべての処理と機能があります。私は何千行ものコードについて話しています。コードが 100 行未満のメソッドはまれです。

クラス全体を書き直すことができず、これらの神のクラスがポップアップし続けると仮定すると、それらに対処する最良の方法は何ですか? どこから始めますか?最初に何を達成しようとしますか?この種のことにどのように対処し、すべてをスタビーにしたいだけではありませんか。

気性を抑えるための戦略があれば、それも大歓迎です。

ここまでのヒント:

  1. テスト範囲を確立する
  2. コードの折りたたみ
  3. 既存手法の再編成
  4. 発見された動作を文書化する
  5. 漸進的な改善を目指す

編集:

Charles Conway は、非常に役立つことが判明したポッドキャストを推奨しています。リンク

Michael Feathers (ポッドキャストの男) は、単純にプロジェクトをソース管理から外して直接操作し、変更を破棄することはあまりにも恐れられているという前提から始めました。私はこれについて有罪であると言えます。

彼は本質的に、あなたがもっと知りたいと思うアイテムを手に取り、それをバラバラにし始めると言った. 依存関係を発見し、それらを壊します。どこまでもそれに従ってください。

大きなヒント 他の場所で使用されている大規模なクラスを使用して、空のインターフェイスを実装します。次に、クラスを使用してコードを取得し、代わりにインターフェイスをインスタンス化します。これにより、コード内のその大きなクラスへのすべての依存関係の完全なリストが得られます。

4

7 に答える 7

9

痛い!私が働いていた場所のように聞こえます。

レガシー コードを効果的に使用する をご覧ください。凶悪なコードを処理する方法に関するいくつかの宝石があります。

DotNetRocks は最近、レガシー コードの操作に関するショーを行いました。それを機能させる魔法の薬はありません。

私が聞いた最善のアドバイスは、テストでコードを段階的にラップすることです。

于 2008-12-12T04:21:42.140 に答える
4

ファイルをリファクタリングできない場合でも、再編成してみてください。少なくともファイル内で論理的に編成されるように、メソッド/関数を移動します。次に、各セクションを説明するコメントをたくさん入れます。いいえ、あなたはプログラムを書き直していませんが、少なくとも今は正しく読むことができます。次にファイルを操作する必要があるときは、あなたが書いたたくさんのコメントがあります (うまくいけば、あなたはそうするでしょう)。プログラムに対処するのに役立ちます)。

于 2008-12-12T04:19:34.267 に答える
4

今の仕事と入社当初を思い出します。彼らは私が何かを書き直すことを許してくれませんでした。なぜなら、「これらのクラスは非常に大きく、よく書かれていない! 誰もそれらを理解できず、ましてや新しい機能を追加することもできなかった」という同じ議論を持っていたからです。

したがって、私が最初に行うことは、変更しようとしている領域の背後に包括的なテストがあることを確認することです. そして、少なくとも、コードを変更して (多すぎる) 引数を持たないようにする可能性があります (うまくいけば)。テストとは、統合テストまたは受け入れテストでコンポーネントの機能をテストし、100% カバーされていることを確認することを意味します。テストが良好であれば、大きなクラスを小さなクラスに分割したり、重複を取り除いたりすることで、自信を持ってコードを変更できるはずです。

于 2008-12-12T04:18:09.290 に答える
3

私もこの状況に遭遇しました。

個人的には、最初にコードを印刷します (多くのページになる可能性があります)。次に、「メインループ」の一部ではない、または単なるヘルパー関数であるコードのセクションの周りにボックスを描画し、最初にこれらのことを理解していることを確認します. その理由は、それらがおそらくクラスの本体内で何度も参照されており、それらが何をするかを知っておくとよいからです。

次に、主要なアルゴリズムを特定し、数字と文字を交互に使用する番号付けシステムを使用して、それらを部分に分解します (見苦しいですが、私にはうまく機能します)。たとえば、4「レベル」の深さのアルゴリズムの一部を見て、番号付けが 1.b.3.e またはその他の恐ろしいものになる可能性があります。レベルと言うとき、必ずしも制御ブロックやスコープを直接参照しているわけではなく、アルゴリズムのステップとサブステップを特定した場所を指していることに注意してください。

次に、アルゴリズムを読んで読み直すだけです。最初は時間がかかるように聞こえますが、これを行うことで、大量の論理を一度に理解する自然な能力が身に付くと思います。また、このコードに起因するエラーを発見した場合は、事前に紙に視覚的に分解しておくと、後でコードを「ナビゲート」するのに役立ちます。これは、頭の中に一種のマップが既にあるためです。

なんらかの UML 形式で記述されるまで、上司が何かを理解しているとは思わない場合、サブステップ レベルが水平に表された異なる「クラス」であり、開始から終了までが上から下へ垂直に表されます。

于 2008-12-12T04:38:30.000 に答える
3

あなたの痛みが分かります。コンピューターでデジタル TV データを処理するという趣味のプロジェクトで、一度このようなことに取り組みました。ハードウェア フォーラムのフェローが、番組を録画したり、オンになっているものをすべて表示したりするための素晴らしいツールを作成しました。さらに、彼は標準に違反している実際の放送信号のバグを回避するという非常に重要な作業を行っていました。彼はスレッド スケジューリングで驚くべき作業を行い、何があってもリアルタイム パケットを失わないようにしました。古い Pentium では、Doom をプレイしながら同時に 4 つのストリームを記録でき、パッケージを失うことはありませんでした。つまり、このコードには膨大な知識が組み込まれています。いくつかの作品を取り上げて、自分のプロジェクトに組み込みたいと思っていました。

ソースコードを入手しました。 1 つのファイル、22,000 行の C、抽象化なし。私はそれを読むのに何時間も費やしました。素晴らしい仕事がたくさんありましたが、すべてが下手でした。1行も1アイデアも再利用できませんでした。

話の教訓がどうなるかはわかりませんが、もし私が仕事でこのようなものを使用することを余儀なくされていたら、一度に 1 つずつ部品を切り落とし、各部品の単体テストを構築し、最終的には許可を求めたでしょう。断片から新しく賢明なものを育てる。 このアプローチは、大きなブリックをリファクタリングして適切な場所に維持しようとするのとは少し異なりますが、レガシー コードをそのままにして、並行して新しいシステムを立ち上げようとした方がよいでしょう。

于 2008-12-12T05:48:39.030 に答える
3

コードの折りたたみが役立ちます。巨大なクラス内で物を動かし、ある程度論理的な方法で整理できれば、さまざまなブロックの周りに折り目を付けることができます。

すべてを非表示にすると、個別のファイルではなく折り畳みを除いて、C パラダイムに戻ります。

于 2008-12-12T04:18:59.977 に答える
2

私が最初に行うことは、まだ何もないと仮定して、現在の動作をボックス化するための単体テストを作成することです。次に、変更が必要な領域から始めて、そのメソッドをクリーンアップしようとします。つまり、変更を導入する前に作業コードをリファクタリングします。一般的なリファクタリング手法を使用して、既存の長いメソッドからメソッドを抽出して再利用し、より理解しやすくします。メソッドを抽出するときは、同様のコードが存在するコード内の他の場所を探し、その領域をボックスで囲み、抽出したばかりのメソッドを再利用します。

独自のクラスに分割できる「一緒にぶら下がっている」メソッドのグループを探します。それらのクラスがどのように機能するかについていくつかのテストを作成し、必要に応じて既存のコードをテンプレートとして使用してクラスを構築し、新しいクラスを既存のコードに置き換えて、それらが置き換えるメソッドを削除します。繰り返しますが、テストを使用して、何も壊していないことを確認してください。

新しい機能/修正をきれいな方法で実装できるように、既存のコードを十分に改善してください。次に、新しい機能/修正のテストを作成し、テストに合格するように実装します。最初からすべてを修正する必要があるとは思わないでください。徐々に改善することを目指してください。

于 2008-12-12T04:19:55.637 に答える