30

あなたの仕事の90%が、非常に大規模で非常に壊れたWebサイトで問題をトリアージすることだけであると想像してください。このWebサイトが、これまでに見た中で最も緊密に結合された、最もまとまりのないPHPコードで書かれていると想像してください。これは、元の開発者を「平手打ち」リストに追加するタイプのコードです。このWebアプリケーションが、4つの非常に異なるパーツ(1つは商用、2つは「再利用」、1つはカスタム)と、1トンの仮想ダクトテープとシムで構成されていると想像してください。ウェブサイトの主要なコンポーネントが実際に正しく機能していないものに依存しているタイプのプログラミング手法が含まれていると想像してください。これらの壊れたものを修正すると、通常、他のものが壊れます。あまりにも多くの悪い経験から、「名前」を分割するなど、Webサイトの一見無害な部分を変更することを知っていると想像してみてください。フィールドを2つの別々の「最初の」フィールドと「最後の」フィールドに分割すると、サイトがひざまずき、何時間ものロールバック、マージ、およびパッチが必要になります。何年にもわたって顧客にコードを捨てて最初からやり直すように懇願することを想像してみてください。しかし、エンタープライズグレードの絶望と手絞りに遭遇しました。次に、ASAP / EMERGENCYチケットを取得して、他のWebサイトでは4時間かかる新機能を実装することを想像してみてください。ただし、このサイトの方がよくわかっているので、40時間見積もり、それをすぐに実行して80時間請求しますが、クライアントは問題ありません。彼らのウェブサイトでそれに慣れています。何年にもわたって顧客にコードを捨てて最初からやり直すように懇願することを想像してみてください。しかし、エンタープライズグレードの絶望と手絞りに遭遇しました。次に、ASAP / EMERGENCYチケットを取得して、他のWebサイトでは4時間かかる新機能を実装することを想像してみてください。ただし、このサイトの方がよくわかっているので、40時間見積もり、それをすぐに実行して80時間請求しますが、クライアントは問題ありません。彼らのウェブサイトでそれに慣れています。何年にもわたって顧客にコードを捨てて最初からやり直すように懇願することを想像してみてください。しかし、エンタープライズグレードの絶望と手絞りに遭遇しました。次に、ASAP / EMERGENCYチケットを取得して、他のWebサイトでは4時間かかる新機能を実装することを想像してみてください。ただし、このサイトの方がよくわかっているので、40時間見積もり、それをすぐに実行して80時間請求しますが、クライアントは問題ありません。彼らのウェブサイトでそれに慣れています。

他にも想像しておくべきことがいくつかあります。

  • 現在、テストはまったくありません。
  • ログインにはgoogleteenの異なるレイヤーがあります。一部の顧客は、実際にはWebサイトのさまざまなセクションに3つの異なるアカウントを持っています
  • 私が「密結合」と言うとき、私はinclude/requireステートメントのループがおそらくケルトノットのようにマップされることを意味します
  • 「最もまとまりがない」とは、MVCのように編成されているものもありますが、実際にはMVCではありません。場合によっては、URIAがファイルBにどのようにマップされているかを確認するだけで数時間かかることがあります。
  • UIは「目立たない」と「アクセスできない」のように書かれており、当時の流行語でした

それをすべて想像すると、適度なレベルのテストカバレッジを達成しようとする価値さえありますか?または、この架空のシナリオで、与えられたものでできる限り最善を尽くし続け、クライアントがこれらの日のいずれかを書き直すことに同意し、それからあなたが書き始めることができることを願って、祈って、おそらく犠牲にする必要がありますテスト?

補遺

あなたの多くがそれを持ち出したので:私は私がこれまでに持っていたあらゆる機会に書き直しの可能性に近づきました。私が一緒に仕事をしているマーケティング担当者は、彼らのコードががらくたであることを知っています、そして彼らはそれが彼らが最初に行った「最低入札」会社のせいであることを知っています。私はおそらく、請負業者としての私の限界を超えて、彼らがこのサイトのホスピスケアを提供するために私に莫大なお金を費やしていること、そしてそれを最初から再開発することによって彼らは非常に迅速にROIを見るだろうと指摘しました。とにかく彼らが望んでいることを実際には行わないので、私はサイトをそのまま書き直すことを拒否するとも言いました。計画はBDDスタイルに書き直すことですが、すべての主要なプレーヤーを1か所に集めるのは困難であり、彼らが何を必要としているかはまだわかりません。いずれにせよ、私はそれが非常に大きなプロジェクトになることを完全に期待しています。

これまでのすべてのフィードバックに感謝します!

4

13 に答える 13

12

しばらくの間、完全なカバレッジが得られない可能性があります。ただし、実装する新しいコード/機能のテストを作成できます。小さく始めましょう。すべてを一度にやろうとしないでください。

また、「レガシー コードを効果的に使用する」という本は一読の価値があるのではないでしょうか?

編集

また、このシナリオと、「プログレッシブ ワイドニング」を使用して悪いコード ベースを良いコード ベースに変換する方法に触れている、ボブおじさんからのこのプレゼンテーションを見ることをお勧めします。

編集 2

自己完結型の関数を見つけることから始めます。渡された引数以外は何も参照しない関数。それらをヘルパー クラスに移動して整理します。これはおそらく一時的なものであり、多くは後で別のクラスに分類されますが、これは重複したコードを特定し、整理を開始するのに役立ちます。次に、これらがどのように使用されるかを見て、これらの使用に基づいてテストを作成します。そして自分の背中を撫でてください。これで、コードを保守可能にする作業が開始されました。

編集 3

絶好のタイミングで、InfoQ は別の記事How To Do Large Scale Refactoring を投稿しました。これは特にこの種のものであり、別の古い記事Refactor or Rewrite?と呼ばれています。また、ミカド メソッドのようなテクニックもあります。1 つのステップで常に必要な動きができるとは限らず、目標を設定して実現するには別の動きをしなければならないことを理解する必要があります。

于 2010-08-23T15:57:03.830 に答える
11

絶対違う。

複数のことが特に機能していない他のものに依存していると言ったら、どうすればそれをテストし始めることができますか?

個人的には、それを破棄して最初からやり直すと思います。80時間かかる4時間の機能?これが誇張であることを願っています。あなたが持っている必要がある頭痛。

コードベースを書き直すという非常に確固たる提案から始めます。手の込んだクライアントは、率直な真実を時々言わなければなりません。壊れたベースで作業する開発者は他に何人いますか? 見栄えの良いコスト/ベネフィット チャートを作成します。

あなたが書いたコードのテストを必ず書いてください。それを無視しないでください。私は、既存のコード ベースにテストを書き込もうとはしないと言っているのです。

于 2010-08-23T15:52:43.477 に答える
7

試してごらん

テストを作成すると、リファクタリングが可能になります。十分に高いレベルでテストを作成すると、毎回テストを書き直さなくてもリファクタリングできるようにすることができます。

サイトのごく一部を試してみる価値はありません (どの部分も完全に分離できないことはわかっていますが、その部分をターゲットにすることはできます)。

たぶん、時間の予算を自分で設定し (手頃な価格/価値のあるものを見つけるのはあなた次第です)、いくつかのテストといくつかのリファクタリングを試してみてください。うまくいかない場合は、ロールバックします。もしそうなら、続けてください。

幸運を!

于 2010-08-23T15:52:48.420 に答える
6

まず、見積もりが実際の半分になることに顧客が慣れている場合は、見積もりを修正してください。見積もりがずれていても顧客が「OK」であることは素晴らしいことですが、実際に必要な労力に見合った見積もりを得ることが重要です。それがなければ、リライトは言うまでもなく、大規模なリファクタリングに同意する顧客はいないでしょう。したがって、見積もりが正しいという履歴を取得してから、プロジェクトのやり直しに移ります。

テストの書き方について。これは、グリーン フィールド プロジェクトよりも、あなたが説明するものにとってさらに重要です。触れるコードのすべての部分で、そこにあるはずの振る舞いをそこにある振る舞いから切り離すことが可能かどうかを自問してください。コードを(テストを使用して)本来あるべき方法で記述し、抽象化のレイヤーを追加して現在の状態にします(そしてそれもテストします)。あなたは混乱に自分が追加されているように感じるでしょう.

それが私が扱ってきたようなものであれば、単一のメソッドをヘルパークラスに引き出して既存のコードにパッチを当てるという順序になるでしょう.システムのその部分にもう一度触れる必要があります。彼らが言うように、「あなたが見つけたよりも良いままにしておく」と、戻ってくるたびに、より良い形を見つけ始めるでしょう. テストは、あなたが見つけたよりも良いものを残すための最良の方法です.

しかし真剣に言えば、リワークを処理する能力についてクライアントが完全に確信する前に、見積もりの​​正確性についてクライアントに確信を持ってもらう必要があります。

于 2010-08-23T18:01:33.003 に答える
5

絶対にテストを書いてください。特に密結合環境では、テストはさらに重要になります (密結合により、1 つの領域でのバグ修正が他の領域に大きな影響を与える可能性があるため)。

さて、これは簡単な作業ではない可能性が高いことを認識してください。テストを作成するには、コードをテスト可能に変更する必要があります。コードを変更するには、テストが必要です。だから、あなたは依存サイクルに巻き込まれています...

ただし、潜在的な利点を見てください。それが本当に価値があるかどうかを教えてくれるはずです。

始めるなら小さく始めましょう。疎結合に見える小さなピースを 1 つ選び、それをテストします。次に、それほど絡み合っていない何かを見つけます。最初にすべての最も緩い部分をテストします (簡単にぶら下がっている果物)。次に、非常にタイトな部分に到達すると、より快適になり、(うまくいけば)本当に何をする必要があるかについてより多くの洞察が得られます.

メリットを享受するために 100% のカバレッジは必要ないことを忘れないでください。テストごとに意味が追加されます...

于 2010-08-23T16:00:33.270 に答える
3

あなたはそれをスクラップすることはできません。顧客はあなたを許そうとはしませんし、とにかくそれが最善の道ではないかもしれません.

したがって、数分かかるはずの修正に 40 時間かかると見積もる代わりに、60 時間を見積もってください。顧客はそれで満足しているようです。修正には 40 を使用し、リファクタリングには 20 を使用します...そして、リファクタリングした内容についてテストを記述します。60 が 100 になったら、120 を使います。修正に 80、リファクタリング/テストに 40。

物事を通常の見積もりに改善するために時間内に構築するか、新しい仕事を見つけます。現在の状況は、私たちの分野を憎むようにあなたを駆り立てるように聞こえます.

于 2010-08-23T18:08:24.100 に答える
2

これは、まったくテスト可能にするために、システムの一部を最初から書き直す必要があるように思えます。その過程で大量のバグが発生することは避けられません。

おっしゃる通り、古いシステムではそこまでの労力を割く価値はありません。

いかなる場合でも、これについてテストを導入しようとはしませんが、できるだけ早く書き直す許可を得るようにします。

クライアントが光を見ていない場合は、プロジェクトのリファクタリングに自分の時間を割く価値があるかどうかを検討してください。クリーンなコードで作業することは、自分の幸福にとってはるかに優れています...

于 2010-08-23T15:54:00.947 に答える
2

最も重要なこと (購入後、レガシー コードを効率的に使用する) は、小さく始めることです。私はいくつかのプロジェクトに取り組んでおり、それぞれ数千行のPHP行があり、多くの場合、単一の関数がなく(オブジェクトについても考えていません)、コードを変更する必要があるときはいつでも、その部分を関数にリファクタリングしてテストを記述しようとします. これは、その部分の広範な手動テストと組み合わされているため、以前と同じように機能することを確認できます. 同様の関数が複数ある場合は、それらを静的メソッドとしてクラスに移動し、段階的に適切なオブジェクト指向コードに置き換えます。

関数への移動から実際のクラスへの変更までのすべてのステップは、単体テストに囲まれています (コードの 90% が SQL クエリであり、信頼できるテスト データベースをセットアップすることはほとんど不可能であるため、あまり良いものではありませんが、それでもできます)動作をテストします)。

多くのコードが繰り返されるため (1 つのファイルで 13 回繰り返される 1 つの SQL クエリが見つかり、そのプロジェクトの他の 50 ファイルではそれ以上の回数が繰り返されることがわかりました)、他のすべての場所を変更することはできますが、それらはどちらもテストされていないため変更しません。また、周囲のコードがそのコードに奇妙な方法で依存していないことを確認することもできません (考えてみてくださいglobal)。とにかくそのコードに触れる必要があるとすぐに、そのコードを変更できます。

これは長くて退屈な作業であり、コードを見るたびに、精神的崩壊に一歩 (または飛躍) 近づいているように感じますが、コードの品質は (ゆっくりと、しかしほぼ確実に) 改善されます。

あなたの状況は非常に似ているように見えるので、私のアイデアがあなたのコードに役立つかもしれません。

要するに

小さく始めて、取り組んでいるものだけを変更し、限られた単体テストのみを書き始め、システムについて学べば学ぶほどテストを拡張します。

于 2010-08-24T14:01:35.667 に答える
1

まず、ブラックボックス、機能テスト、接続された部品、またはあちこちの部品を実行します。これにより、継続的な開発とリファクタリング/書き換えがはるかに簡単になります。

そこに行って、それをしている。

ユニットテストの追加を開始できるようになるまでしばらく時間がかかりましたが、最終的にはそこに到達しました。

まだ防弾にはほど遠いですが、コードの変更を検証するのを待っているテストスイートがあることがわかっている場合、すべての開発者はあえて変更/修正することに自信があります。

于 2010-08-23T16:06:55.117 に答える
1

あなたのシナリオから、無害な変更によって影響を受ける傾向があるコードの脆弱な領域 (または少なくとも絶対に機能する必要がある領域) の長いリストが必要です。このリストに対してテストを書くことができれば、実装している変更によって何かが壊れたときをすばやく見つけることができます。

于 2010-08-23T19:09:56.767 に答える
0

アプリケーションがどのように機能するか、またはそれ以上の機能を示す優れたBDD(ドメイン)モデルを作成するために、さらに40時間/反復で請求することを検討することをお勧めします。これにより、必要な機能を文書化できる優れたフレームワークが作成されます。モデルが十分に完成したら、モデルを動作するアプリケーションに変換するために必要な時間を見積もることができます。

于 2010-08-24T14:22:58.397 に答える
0

理論的には、間違いなく。緊密に結合され、バグが多いメンテナンス プロセスほど、テストの重要性は高くなります。実際には、立ち去って別の日を生きましょう!

于 2010-08-23T15:55:01.467 に答える
0

物事が確実に動作する場合は、それらをテストできますよね? ほとんどの場合、システムは正常に動作するため、これらの成功条件をテストできます。

..「名前」フィールドを 2 つの別個の「最初」と「最後」のフィールドに分割するなど、Web サイトの無害な部分は、サイトをひざまずかせ、何時間ものロールバックを必要とします。

姓名などのフィールドを分割することは、大きな可能性を秘めているように思えますが、教訓を学んだように思えます。少なくとも、フル サイズのテスト システムにいくらかの資金を調達し、本番データをシステムに自動的に移動するための手順を整備して、これを完全にテストできるようにしてください。

かなりひどいように聞こえますが。オレの履歴書をほこりにする時間はありますか?

于 2010-08-24T00:22:49.663 に答える