いつBIGが答えを書き直しますか?


278

Big Rewritesに関する質問を読んでください。私は自分で答えたいと思っていた質問を思い出しました。

Struts 1.0を使用して古いJavaで書かれた、恐ろしいプロジェクトがあります。テーブルは一貫性のないリレーションシップを持っているか、リレーションシップがまったくないか、プライマリキーまたはフィールドがプライマリキーであることを意図していますが、一意ではありません。どういうわけか、アプリのほとんどは「機能する」だけです。ほとんどのページは再利用(貼り付けられたコードのコピー)およびハードコーディングされています。プロジェクトに携わったことのある人は誰でも、何らかの形でそれを呪いました。

今では、この恐ろしいアプリケーションの全面的な書き換えを上級管理職に提案することを長い間考えていました。私は個人的な時間でゆっくりと試みていますが、それを実現するための専用のリソースが必要だと思います。大きな書き直しに関する記事を読んだ後、私は再考しています。そして、上司に私の書き換えをサポートするように説得したいとき、それは良くありません。(私はかなり小さな会社で働いているので、提案は承認される可能性があります)

TL; DRいつ答えが大きく書き換えられ、それをサポートするためにどのような引数を使用できますか?



6
それは古いのですが、それは古典的だ-ジョエルの「あなたが行うべきではありません物事、パートI」joelonsoftware.com/articles/fog0000000069.html
Mawg

これは素晴らしい質問です。非常に関連性の高いこの状況は、ソフトウェアエンジニアリングで頻繁に発生します。
ブラッドトーマス

回答:


325

申し訳ありませんが、これは長くなりますが、複数の書き換えプロジェクトの設計者および開発者としての個人的な経験に基づいています。

次の条件により、何らかの書き換えを検討する必要があります。その後、どちらを実行するかを決定する方法について説明します。

  • 開発者の立ち上げ時間は非常に長くなります。新しい開発者を増やすために(経験レベルで)以下よりも長くかかる場合、システムを再設計する必要があります。ランプアップ時間とは、新しい開発者が最初のコミットを行う準備が整うまでの時間を意味します(小さな機能で)
    • 大学卒業直後-1.5か月
    • まだグリーンですが、以前に他のプロジェクトに取り組んでいました-1か月
    • 中レベル-2週間
    • 経験豊富-1週間
    • 上級レベル-1日
  • 既存のアーキテクチャが複雑であるため、展開を自動化できません
  • 単純なバグ修正でも、既存のコードの複雑さのために時間がかかりすぎる
  • コードベースの相互依存性のために、新機能は時間がかかりすぎ、コストがかかりすぎます(新機能は分離できないため、既存の機能に影響します)
  • 既存のコードベースの相互依存性のため、正式なテストサイクルには時間がかかりすぎます。
  • あまりにも多くのユースケースが実行される画面が少なすぎます。これにより、ユーザーと開発者のトレーニングの問題が発生します。
  • 現在のシステムにある技術はそれを要求します
    • 技術の経験を持つ質の高い開発者を見つけるのは難しい
    • 廃止されました(新しいプラットフォーム/機能をサポートするためにアップグレードすることはできません)
    • 単にはるかに表現力豊かな高レベルの技術が利用可能です
    • 古いテクノロジーのインフラストラクチャを維持するコストが高すぎます

これらはかなり自明です。完全なリライトとインクリメンタルなリビルドをいつ決定するかは、より主観的であり、したがって、より政治的な責任を負います。確信を持って言えることは、決して良いアイデアではない断言することは間違っているということです。

システムを段階的に再設計でき、そのようなことに対するプロジェクトスポンサーシップの完全なサポートがある場合は、それを行う必要があります。ただし、ここに問題があります。多くのシステムは、段階的に再設計することはできません。これを防ぐために私が遭遇したいくつかの理由を以下に示します(技術的および政治的の両方)。

  • テクニカル
    • コンポーネントの結合は非常に高いため、単一のコンポーネントへの変更を他のコンポーネントから分離することはできません。単一のコンポーネントを再設計すると、隣接するコンポーネントだけでなく、すべてのコンポーネントに間接的に変更がカスケードされます。
    • テクノロジースタックは非常に複雑であるため、将来の状態設計では複数のインフラストラクチャの変更が必要になります。これは完全な書き換えでも必要ですが、インクリメンタルな再設計で必要な場合は、その利点が失われます。
    • コンポーネントを再設計すると、とにかくそのコンポーネントが完全に書き直されます。これは、既存の設計が非常に複雑で、保存する価値がないからです。繰り返しますが、これが当てはまる場合、あなたは利点を失います。
  • 政治的
    • 段階的な再設計にはプロジェクトへの長期的なコミットメントが必要であることをスポンサーに理解させることはできません。必然的に、ほとんどの組織は、段階的な再設計によって生じる継続的な予算流出に対する欲求を失います。この食欲不振は書き直しにも避けられませんが、スポンサーは部分的に完全な新しいシステムと部分的に廃止された古いシステムに分割されたくないため、継続する傾向があります。
    • システムのユーザーも「現在の画面」に執着しています。この場合、システムの重要な部分(フロントエンド)を改善するためのライセンスはありません。再設計を行うと、新しい問題から始まるため、この問題を回避できます。彼らはまだ「同じスクリーン」を手に入れることを主張しますが、あなたは押し戻すためにもう少し弾薬を持っています。

増分再編集の総コストは、完全な書き換えを行うよりも常に高くなりますが、通常、組織への影響は小さいことに注意してください。私の意見では、書き直しを正当化でき、スーパースターの開発者がいる場合は、それを行います。

それを完了するまで政治的な意思があると確信できる場合にのみ、それを行ってください。これは、エグゼクティブとエンドユーザーの両方の賛同を意味します。それなしでは、失敗します。これが、ジョエルが悪い考えだと言う理由だと思います。エグゼクティブおよびエンドユーザーのバイインは、多くの建築家にとって双頭ユニコーンのように見えます。それを積極的に販売し、完了するまで継続的にキャンペーンを行う必要があります。それは難しいことであり、あなたは、成功を望んでいない人に評判をかけることについて話している。

成功のためのいくつかの戦略:

  • ただし、既存のコードを変換しようとしないでください。システムをゼロから設計します。そうしないと、時間を無駄にします。悲惨な結果にならなかった「変換」プロジェクトを見たことも聞いたこともない。
  • 一度に1チームずつ、ユーザーを新しいシステムに移行します。既存のシステムで最も苦労しているチームを特定し、最初にそれらを移行します。彼らに口コミで良い知らせを広めましょう。これにより、新しいシステムが内部から販売されます。
  • 必要に応じてフレームワークを設計します。実際のコードを見たことがないこのフレームワークから始めてはいけません。
  • テクノロジースタックをできるだけ小さくしてください。過剰に設計しないでください。必要に応じてテクノロジーを追加できますが、それらを取り出すことは困難です。さらに、レイヤーが多いほど、開発者がより多くの作業を行うことができます。始めから難しくしないでください。
  • ユーザーを設計プロセスに直接関与させますが、ユーザーにその方法を指示させないでください。優れた設計原則に従えば、より良いものを提供できることを示して、信頼を獲得します。

25
Joelのポイントは、書き換えを行うと、古いコードに蓄積された知識が失われるということです。
quant_dev

14
@quant_devは一部はありますが、ときどき書き直すと、古いシステムのバグの多くは、理想的なシステムの動作方法に厳密に関連するロジックではなく、古いシステムの動作方法に起因することがわかります。
Tjaart

13
ジョエルは、書き換え中にアプリケーションに新しい機能を追加しないため、失敗すると言います。書き換えの唯一の目的は、技術的負債の一部またはすべてを排除することです。確かに、これは些細なことではありませんが、競合他社がソフトウェアに新しい機能を追加している場合、単に技術的な負債を取り除くだけでは危険です。
ロバートハーベイ

25
私はこれらすべての基準に適合するコードベースで作業しましたが、Big Rewriteはまだ失敗し、いくつかの点で、以前のカオスとは非常に異なるが、はるかに管理しやすい。IMOは、リファクタリングが完全に不可能になった場合にのみ、機能を追加したり、現在のお客様にコストがかかっているバグを修正したりすることからすべての焦点を取り除きます。本当に解読不能なコードを話さない限り、モジュラービットを引き出して再利用しやすくすることができないチームは、とにかく大きなrwに対して十分に再設計できないでしょう。
エリックReppen

11
これは有用な答えですが、いくつかの点で間違った印象を与えるため、幻想的ではありません。たとえば、「インクリメンタルに再編集するための総コストは、完全な書き換えを行うよりも常に高いことを覚えておいてください」 -その文の「常に」という言葉は間違っています。 「完全な書き換え」はそれを提供しませんが、既存の設計の。確かに、私は実際にそのような状況にいたため、100Kを超えるLOCアプリケーションを部分的に完全に書き直し、部分的には書き直していなかったことを知っています。
Doc Brown

109

私は2つの大きな書き直しに参加しました。最初は小さなプロジェクトでした。2番目は、ソフトウェア会社の主要製品でした。

いくつかの落とし穴があります。

  • 書き換えは常に予想よりも時間がかかります。
  • 書き換えは、お客様に直接的な影響や利点をもたらしません。
  • 書き換え専用の容量は、顧客のサポートには使用されません。
  • 100%のドキュメントがない限り、書き換えによって機能が失われます。

書き換えが本当の答えになることはめったにありません。何も失うことなく、多くのリスクなしに、多くのコードをリファクタリングできます。

次の場合、書き換えが答えになる可能性があります。

  • 別の言語またはプラットフォームに切り替えています。
  • フレームワーク/外部コンポーネントを切り替えています。
  • 既存のコードベースはメンテナンスできなくなりました。

しかし、リファクタリングを使用した遅いアプローチを強くお勧めします。リスクが少なく、顧客を満足させます。


11
リファクタリングアプローチの場合は+1。多くの場合、既存のシステムを書き換えて維持するのに十分な時間または工数がありません。
ライアンヘイズ

これは現在、デモアプリに使用されています(最近購入した顧客はいないため、今が再作成に最適な時期だと考えました)。
ジョン

4
@John:幹部として、営業チームがまだ顧客を獲得していないアプリケーションの書き直しを許可するのは非常に困難です。正直なところ、私はそれにある程度の時間を与えてから、何をすべきかを決定します。興味がなければ、私は全部を捨てて、他にやることを選びます。
NotMe

4
最近、JavaでVisual Basicアプリケーションを書き直しました。これにより、Windows(Java GUIなし)でサービスとして実行できるようになりました-顧客にとってのメリット。

4
「書き換えには直接的な効果や顧客へのメリットはありません」-これは多くの場合、神話です。新しいフレームワークは多くの生産性の向上を「組み込み」で提供するため、実装が不可能または非常に高価です。たとえば、vb6アプリを.netアプリにアップグレードすると、ユーザーは(64ビットアーキテクチャにより)大きなファイルを開くことができるため、エンドユーザーが人為的に作業を分割する必要がなくなります。
スティーブン

72

次の場合に書き換えの時間です:

アプリケーションを書き換えて、書き換えたアプリケーションを維持するコストは、現在のシステムを長期間維持するコストよりも低くなります。

現在のものの維持をより高価にするいくつかの要因:

  • この言語は非常に古いので、それを知っている人にそれをプログラムするために多額のお金を払わなければなりません(COBOL)。
  • (残念ながら、経験から)システムは非常に古いハードウェアアーキテクチャ上にあるため、EbayとCOLLECTの部品を探し回って、実行されているマシンに追加する必要があります。これは「ハードウェアライフサポート」と呼ばれ、部品が希少になると価格が上がるか(絶対に)枯渇するため、高価です。
  • 非常に複雑になったため、//Here be dragons.コメントはコード全体に渡ります。
  • あなたはいつもこのthisい獣にパッチを当てているので、他のプロジェクトを書いて会社に新しい価値を加えることはできません。

それがまさに私が参加した書き直しを促したものです。コードがなかったので、壊れやすい、および新機能を追加するコストそうすることを、高くない書き換えはもはや選択肢でした。
フランクシェラー

16
ここでポイント2について笑っています。
ポールネイサン

4
@Paul:クライアントから私に言われたときもそうでした。それから彼らは本気であることがわかりました...そして書き直しのために要件収集をしているのです。なんてエキサイティングな一日だった。
ライアンヘイズ

3
問題は、コストの測定方法です。

2
私はこの応答が好きで、面白くて真実です。「少ない」の直前に「定量的に」を追加したいと思います。何度も申し立てをするのは簡単ですが、無駄な時間を定量化できることが重要です。
ケビン・スー

17

プロジェクトのアーキテクチャに根本的な変更が必要な場合は、新たに開始する時間になる可能性あります。

それでも、新しいプロジェクトで再利用する価値のある大量のコードが存在する可能性があります。

ただし、公正な警告に注意してください。現在のプロジェクトでは、数え切れないほどの実際の使用時間でビジネスルールがテストおよび改良されています。これは、ゼロから始めたプロジェクトには当てはまりません。

時間枠や直感は、このような抜本的な尺度の適切な尺度ではないかと思います。この一連の行動に参加するには、明確で防御可能で十分に理解された理由が必要です。


3
「大規模なコードの再利用」には細心の注意を払う必要があります。これにより、未使用のレガシーコードやコード構造の不良が発生する可能性があります。私の意見では、リファクタリングはより良い解決策です。
-mrwooster

1
同意した。その声明の一部は、「新しい」プロジェクトへの「リファクタリング」として解釈される必要があります。つまり、あなたが実際にその抜本的なパスにすでにコミットしている場合です。他の人が述べたように、これはほとんど行われるべきではない極端な希少性です。
ダン・マクグラス

1
+1。また、書き換えには時間がかかり、その間にメンテナンスを行う必要がありますが、両方のコードベースで同じ変更を行う必要があります。
ラリーコールマン

12

Kramiiの答えとJoelの意見には同意しますが、書き直すことが適切な場合があります。長寿命のアプリケーション(私は10〜20年以上話している)では、メンテナンスは時間とともにますます高価になります。これは、迅速なメンテナンスパッチのために元のアーキテクチャが犠牲になるため、コードがますますスパゲッティっぽくなるためです。また、古いテクノロジーの開発者は、より稀で高価になります。最後に、ハードウェアは古くなり始め、古いアプリケーションを実行する新しいハードウェア、オペレーティングシステム、フレームワークなどを見つけることがますます難しくなります。また、ビジネスは進化し、古いシステムは組織のビジネスニーズを満たしていない可能性が高く、新しいシステムはそうではありません。

したがって、継続的なメンテナンスコストのすべてと、ビジネスに対する新しいシステムの潜在的な利点と、ゼロから物を書き直すコストとを比較検討する必要があります。ことが非常に書き換えの費用についての見積もりでは悲観的。ほとんどの場合、予想よりもコストがかかり、時間がかかります。


ホフスタッターの法則に言及するための+1 。
-Baelnorn

11

やめる!書き換えが答えになることはほとんどありません。たいていの場合、リファクタリングがより良い方法です。


もちろん、書き換えが正当化される場合があります

  • 移行ツールが存在しない(または十分に安価に記述できない)新しいプラットフォームに切り替えています。
  • 書き換えられるアプリケーションは簡単です。
  • 元のアプリケーションのソースコードは失われ、回復は書き換えよりも高価です。
  • 既存のアプリケーションによってカプセル化されたビジネスルールの大部分は適用されなくなりました。
  • 既存のコードのアクティブユーザーはほとんどいません。
  • 書き換えを行うためのリソース(時間、才能、ツール)があります。
  • 法的または実際的な理由により、既存のアプリケーションを実稼働環境で実行することはできません。

書き換えよりもリファクタリングを推奨する理由を理解するには、書き換えに関係することを考慮してください。絶対です:

  1. 既存のアプリケーションが行うことのニュアンスを理解します。カプセル化するすべての微妙なビジネスルール、それが動作する環境(人間と技術の両方)、および現在のソリューションの長所と短所を考慮する場合、これは通常簡単ではありません。多くの場合、この情報が存在する唯一の場所(存在する場合)は、既存のアプリケーションのソースコード内です。書き換えを実行する主な理由の1つは、既存のコードを理解して保守することが難しいことです。

  2. テストされ、信頼できる新しいアプリケーションでこの機能(またはその更新バージョン)を再現します。既存のコードは開発者には理解されないかもしれませんが、通常はそのユーザーにはよく理解されています。現在のビジネスニーズを満たしていない可能性がありますが、少なくとも、さまざまな状況でアプリケーションが何をするかを伝えることができます。

リファクタリングの大きな利点は次のとおりです。

  • あなたは物を一度に一つずつ取ることができます。
  • すべての変更は、既存の動作中のアプリケーションのコンテキストでテストできます。
  • 既存のコードがどのように機能するかについての仮説は、小さな変更を加えて何が起こるかを観察することでテストできます。
  • 多くの場合、変更は一度にすべてではなく段階的にユーザーに配信できます。
  • リファクタリングの初期段階から学習することで、リファクタリングの後の段階を知ることができます。
  • プロセスを途中で放棄した場合でも、コードベースがよりきれいになるという利点があります(ユーザーまたは開発者に利益を提供するために完了する必要がある書き換えと対照的です)。

また、書き直した場合、多くの新しいバグや混乱が新しいコードベースに導入されることが保証されていることも忘れないでください。


2
リファクタリングの方が書き換えよりも優れている理由を説明することで、この答えを拡張できますか?そしてときでしょうリライトは、答えは?
ギャブリン

書き換えは、ほとんどの場合、別の衣装の同じ混乱であるという事実を考えると、あなたは正しいです。その単一の問題を排除できるなら、あなたは間違っています。適切な人々がそれを行うとき、絶対的なものはありません。
JensG

10

このグラフィックは、コードベースの品質とアプリケーションのビジネス価値の関数です。

ここに画像の説明を入力してください

このチャートは、レガシーソフトウェアのリエンジニアリングが正当化される場合と正当化されない場合のガイドのふりをしています。たとえば、ソフトウェアのビジネス価値が高く、コードの品質が低い場合、リエンジニアリングが正当化されます。


4
ビジネス価値の低いプロジェクトの書き直しに投資するのはなぜですか?ただそれをスクラップ!
ヨルゲンフォグ

それが「交換または...」と述べている理由です。価値のあるものに置き換えることができます。または、価値のあるものにします。しかし、あなたにはポイントがあります。それを編集して「スクラップ」オプションを追加します。
Tulainsコルドバ

8

私は私のキャリアの中で、大きな書き直しが答えである唯一の状況にいると思います:

会社の合併、システム機能の大きな重複。多くの多くのシステムが統合され廃止されましたが、他のシステムはまだ進行中です。

私はまだ生きている他の会社からシステムを継承しました。巨大なコードベースがあり、これは私たちと非常によく似た複数の部門をサポートしていましたが、設計とフレームワークがまったく異なります。使用しているビジネスセクターは1つだけです。これにより、ゾンビ状態でこのことを存続させるのに十分なお金を稼ぐことができます。古い専門知識はすべてなくなり、ドキュメントはありません。サポートの負担は高く、毎週失敗します。当社はこの特定のセクターのビジネスをサポートしたことがないため、当社のシステムに統合されていません。そのため、当社には機能や専門知識がありません。

これは、書き換えが必要な1つのケースのようです。この巨大な問題を把握し、このビジネス専用の機能を少し引き出して、既存のシステムに追加する必要のある部分を書き直さなければならないようです。それが完了すると、既存のシステムがこの新しいセクターをサポートできるようになり、この獣は悲惨な状況から抜け出すことができます。そうでなければ、私は正気を失います。


雇用主は顧客と話をして状況を説明し、長期的には貯蓄するため、最初にもっとお金を払わなければならない場合でも、彼らを助ける最善の方法を見つける必要があるように思えます。

7

私は、Y2Kを処理するためにアップグレードされたいくつかのDOSアプリケーションを持ち、Windows 16ビットアプリとして書き直された後、1つの追加の「小さな」機能を備えた32ビットアプリとして完全に書き直された小さなソフトウェア会社で働いていました1人の顧客)が構造全体に影響を与えました。

16ビットコードを32に移動することは1人で1か月でできたはずですが、NOOOOOOOOO、私たちはそれを作り直さなければならなかったので、Sooooooooooの方がはるかに優れています。このことは、他の業界に適応させることができ、完全な仕様と擬似コードが開始される前に持っていました。仕様は作成されましたが、実際のコードを書く時間すらありませんでした。遅くリリースされ、16ビットの「開始」よりも多くのバグがありました(v.3.0で、最終的に誰かが新しいバグを報告せずにほぼ1週間になった時点)。

同じアプリケーションを3〜4回書き換えると、いくつかの改善がもたらされると思いますが、GUIフロントエンドをそれほど正当化できるとは思いません。

これは、テクニカルサポートの責任者としての私の最初のIT業務でした。配布用のソフトウェアを開発しない方法についての本を書くべきです。明らかに多くの間違いを犯しましたが、アプリケーションを書き直し続けたという事実は、無能さをさらに悪化させました。


5

コードがStrutsを使用していなかっただけで、あなたと非常によく似たケースがありました。私が代わりにしたことは、特にがらくたで、多くの問題を引き起こしている対象地域でした。このターゲットを絞ったアプローチにより、徐々に改善されました。

2年以上にわたり、強化作業と並行してリファクタリングに取り組みました。私たちは常に「ハードニング」タスクをプロジェクト計画に組み込みました。うまく機能しなかった特定の領域に焦点を当てることで、私たちは支出に見合うだけの価値を得ました。働いたものは私たちが放っておきました。また、この作業が通常の開発の過程で行われ、リリースされたことも重要です。大規模な書き直しの問題は1年以上続いた後、戻ってきたときにすべての問題がとにかく変わり、いくつかの厄介なバグが滑らかになり、ROIを失いました。

すべてを書き直したことはありません。しかし、私たちはそのプラットフォームを新しい仕事に使うのをやめ、大きな新しいプロジェクトに新しい新鮮なプラットフォームを売り込みました。それは承認され、私たちは妥当な時間で素晴らしい製品を提供しました。


5

そこで、ここで私は机に座って、1つの大きなaspxファイルとその背後にあるデータベースの絶対的な混乱のコードを書き直し、MS AccessインターフェースをMsSQLに置き換え始めました。

このaspプログラムには、次のようなものが散らばっています

  • include(close.aspx) 内部には、最後に開いたデータベース接続を閉じるコードが1行あります。
  • レガシーコードはランダムにコメントアウトされました
  • セキュリティを考慮しない
  • スパゲッティコード、数千行。すべて1つのファイルに。
  • 名前の背後に明確な意味のない関数と変数

少し変更する必要がある場合は、悪夢モードでカルトーの5つのゲームを同時にプレイするようなものです。

機能を複製し、業界の他のユーザーにカスタマイズおよび販売可能な製品を作成するために雇われました。問題は、このことはすべてのビジネスニーズを満たすために過去10年にわたって書かれてきたことです(まあ、とにかく5または6シグマと言います)。

製品を販売したくなかった場合、彼らはおそらく彼らが望むもののほとんどを行うので書き直しを必要としなかったでしょう-おそらくエレガントではありませんが、良いコードを作るためにお金を使うことは賢明ではありませんでした「同じことをする。」


4

ジョエル・スポルスキは、この上の優れた記事があります: あなたが行うべきではありません物事、パートI

あなたが伝えることができるタイトルから、その片側(彼はあなたがコードを投げてはいけない理由について話します)IMO、それに多くの真実があります、最近、いくつかの開発者が言ったExcelの25周年でchannel9ビデオを見ました今日でも、ソースを調べた場合、リビジョンをチェックして、20年前に書かれたexcelが使用したコードに戻ることになります。

あなたは100%確信できません(Netscapeでさえ間違いを犯すとき(Joels記事から))、は悲観的であり、コードを捨てることが好きなので、Joelの記事が神から送られた感じました時間がありますが、私はこれがたった今非常にコストがかかることに気付きました。

具体的な答えを出すには、コスト対価値の徹底的な分析を行う必要があると言います

私の現実世界:v0.6を開発中のSilverlightアプリには、これまでにコードを複雑にする非同期呼び出しが大量にあります。今週、Reactive Extensionsを発見したので、ほとんどのコードを書き直したいのですが、今では顧客に何を伝えますか?プログラムは完全に正常に動作します(メモリリークが発生します)が、気にしませんか?何かをやり直したいので、もう2〜3週間かかっているとは言えません。ただし、自由時間にコード分岐し、コードを書き直して再生します。

ちょうど2セントで大丈夫!?


設計時にまだ知らないことがあるため、最初の実装はしばしば最適ではありません。これは通常、最初からやり直すのではなく、形にリファクタリングできます。これは、おそらく正しいことを行っいるためです。そうでない場合は、概念実証であり、頻繁に破棄する必要があります。

分岐の場合は+1。多くの人が「書き直さないで」と言うのは、古いコードを捨てているように見えるからです。しかし、そうではありません。並列コードベースを使用できます。
lunchmeat317 14

公平を期すために、もしあなたがジョエル・スポルスキーに助言を求める人なら、あなたは完全な書き直しをすべきではありません:-)そして、そうでなければ、すべての利害関係者にジョエルの議論が考慮されない理由を納得させる場合にのみ書き直すべきですあなたの特定の場合。
gnasher729

3

既存のソリューションは拡張できません。

MS Access、あなたを見ています。


あなたが正しいものを見ているかどうかはわかりません。ジェットレッドは、これまでスケールすることを意図したものではありませんでした。
JensG

これは質問にどう答えますか?
gnat

3

Joelによると、大きな書き直しは、企業が犯す可能性のある最悪の戦略的ミスです。

してはいけないこと、パートI

...最初から始めるとき、あなたが初めてやったよりも良い仕事をするだろうと信じる理由全くないことを覚えておくことは重要です。まず第一に、バージョン1に取り組んでいたプログラミングチームはおそらくいないので、実際には「より多くの経験」はありません。古い間違いのほとんどを再度行い、元のバージョンにはなかったいくつかの新しい問題を導入します。

古いマントラのビルド1は、大規模な商用アプリケーションに適用すると危険です。実験的にコードを記述している場合、より良いアルゴリズムを考えるときに先週書いた関数をリッピングすることができます。それはいいです。クラスをリファクタリングして、使いやすくすることができます。それも結構です。しかし、プログラム全体を捨てることは危険な愚行であり、Netscapeが実際にソフトウェア業界での経験を持つ大人の監督を受けていれば、彼らはそれほどひどく足を踏み入れていないかもしれません。


5
うん。私はそれに対するいくつかの反論を探していました。それは時々行わなければなりません。
ジョン

3
すべての書き換え引数は、Joelの記事への参照なしでは完全ではありません。私が言ったことは、この記事にはいくつかの良い点がありますが、ご自身で考えてください。たぶん、あなたは記事に同意する理由を言っているべきです。私はジョエルに個人的に同意しません-単に悲しみを終わらせるピットにさらに自分自身を退屈させるよりも、新しい穴を掘るほうが良い場合があるからです。いずれにせよ、書き直しは、潜在的なビジネスプロセスを再評価のために表面化させると思います。
アフマド

Joelsの記事は、物事いかにうまくいかないかを注意深く説明しているので良いものです。

6
Joelは、Netscape Navigatorブラウザの例を使用しています。それは、大きな予算で競争に対抗する大規模な成長曲線の真っwas中にあった消費者向け製品です。これはNetscapeにとって戦略上の誤りでした。一方、内部のカスタム「エンタープライズ」ソフトウェアプロジェクトは異なります。市場シェアを急いでいるわけではありません。すべてのユーザーが競争力のある製品に移行する危険性はありません。それはビジネス上の決定に帰着します:書き換えのコストは長期的にはそれ自体に支払うのでしょうか、それともビジネス目標を達成するための最良の方法でしょうか?
スコットホイットロック

ジョエルは「ハードな方法を学ばなければならないという決定が文書化されていないことを決して知らない」という重要な概念に当たったと思った
MathAttack

2

決して、常にリファクタリングする-真実は、コードがあなたによって書かれたものである場合-あなたはそれ以上改善することができないだろう。

テクノロジーを変更したくない限り、コードには構造がありません(PHP Webサイトでかなり前に見ましたが、著者はinclude / class / functionの代わりにスパゲッティをコピー/貼り付けしただけです)または他の人から何かを引き継ぎました非常にひどく書かれています。

すべてをブラックボックスとして設計する必要があります。モジュラー、シンプルなAPI、内部の内容...それはそれほど重要ではありません:)スパゲッティがある場合は、ブラックボックス内で閉じることができるので、良いコードを汚染することはありません。



+1私はあなたの意見が好きです、新しいAPIのセットへの書き直しについてのあなたの考えを知りたいですか?(以下の私の答えを参照)
ギデオン

はい、これらは良い点です。MicrosoftはwinXPコードを書き直したため、最初のVista製品版ではファイルの削除/コピーを取得することさえできませんでした。彼らがコードベースをただ進歩させていたとき、私たちは絶えずより良い品質を得ていますが(W3.11 => W95 => W98 => ME => XP)、彼らが多くの中核部分を書き直したVistaは災害でした。新しいAPIの場合...現在のコードを分離して、できる限り多くのコードを保持し、上位層で新しいAPIを使用します。例えば。コアクラスはそのままですが、新しいAPIを使用して統合が行われます。すべてが非常に乱雑で、0から開始する以外に何もできない場合を
除きます。-スラウェック

1
「...真実は、コードがあなたによって書かれたものである-あなたはそれ以上改善することができないだろう」十分な担当者がいれば、この投稿に投票します。それは、最も非現実的で非現実的であり、人々が書いたコードが過去に書いたコードの改善であるという点で、どういうわけか人々が進歩できないことを意味します。
JᴀʏMᴇᴇ

1
@JᴀʏMᴇᴇ:同意-初めて実装したときに何も学ばず、経験も得られなかった場合、および/またはより多くの知識/経験/後見があるために今より良い仕事をすることができない場合。あなたはジャガイモであり、プログラマーではありません。
ブレンダン

2

書き換えを正当化する主な理由は、プラットフォームの変更にあると思います。たとえば、WindowsデスクトップGUIアプリケーションがあり、会社の所有者が次のバージョンをWebベースのアプリケーションにすることを決定した場合。常にではありませんが、私の経験では、ほとんどの場合、元の開発者が非常にモジュール化された再利用可能なコードを作成しない限り(これはほとんど発生しません)、書き換えが必要です。


2

「私がXIに行くのなら、ここから始めないだろう」という古典的なジョークがあります。

私は一度仕事に就きましたが、雇用主の最大の動機は、才能を持ってビジネスに不可欠なアプリの長期延期のリライトを立ち上げることでした。私が尋ねることができなかった質問は、そもそもなぜこのような状況に陥ったのですか?原因が赤旗であったかどうか

  • 獣を維持し、段階的にリファクタリングする機能を追加することへの過度のプレッシャー、

  • 部門の能力が少なすぎる、

  • 増分作業のためのクライアントまたは経営陣からのバイインが少なすぎる、

または何でも、そしてこれは問題が耐えられないレベルに達するまではがれさせます。

したがって、大規模な書き換えはおそらく非常に悪いアイデアであるという点でJoelに同意するつもりです- 主要な書き換えが必要であると思われる背後にあるすべての根本的な理由が対処されたという確固たる証拠がない限り、あなたはおそらくやがて問題を繰り返します。


2

書き換えにより、組織が競争力を提供する戦略を追求したり、現在のアーキテクチャでは対応できない方法で顧客により良いサービスを提供できるようにしたりするときの答えです。

代わりに、管理上の心配を軽減するために書き換えが頻繁に発生します。

  • すべてが.NETにある必要があります。
  • 開発者は、コードがひどい、
  • 技術的に遅れています
  • システムをサポートするリソースを見つけることができません。また、非常に頻繁に、
  • 10年が経ちました。

これらの心配のほとんどは実現せず、もしそうなら、それらを処理することができます。ただし、最後の1つは最悪です。基本的には、理由はありません。

はい、車のように、システムは摩耗の兆候を示し始めます。これは、定期的なサービスによって軽減できます。あなたは、彼らが小さな予防的メンテナンスがどのように役立つかについて彼らが言うことを知っています。投資として、定期的なサービス(つまり、リファクタリングと標準化)は、ほとんどの場合、書き換えよりもコストがかかりません。

ただし、最終的には書き換えが必要になると予想する必要があります。日付を設定し、暫定的に計画しますが、次のような説得力のある理由が得られるまで、日付が他の戦略的目標を実現するために遅延が近づくにつれて...

近年、私たちは大きなアカウントを獲得する機会を失いました。なぜなら、タイムリーまたはコストのかかる方法で彼らのニーズに応えることができなかったからです。私たちのシステムは、カスタマイズをプラグインできるようにする拡張可能なアーキテクチャを使用して書き換えられます(現在のようにハードコードされていません)。これにより、特別なニーズを持つ顧客に対応する時間とコストが劇的に削減されます。より多くのアカウントを獲得し、現在のお客様のニーズによりよく応えます。


あなたはその方向にリファクタリングできるはずです。リファクタリングするとき、次の機能を簡単に記述できるように、必要な柔軟性を作成することを念頭に置いています。
イアン

1

目的の機能を提供するには、まったく新しいテクノロジーに移行する必要があります。

「完全に新しい」:書き直しを計画しているが、同じプラットフォームを使用する場合、リファクタリングと慎重な再構築がほぼ確実に優れたソリューションです。ここで使用される「プラットフォーム」はやや曖昧です。言語、おそらくOS(LinuxからWindows、またはその逆へ拡張)を含むと考えてください。しかし、フレームワーク(StrutsをSpringに置き換えるなど)はおそらくないでしょう。

「必要な機能を提供する必要がある」:2000年頃、私はJavaの主要なサーバーコンポーネントをC ++から書き換えて、すぐに使用できるスレッド、オブジェクトキャッシュ、クライアント制御トランザクションを有効にするプロジェクトを開始しました。当時、私たちがサポートしなければならなかったC ++用の複数のスレッドライブラリがあり、データベースコードの多くをスレッド対応にするには、ほぼ完全な書き換えが必要でした。クライアント制御のトランザクションに関しては...古いアーキテクチャでは起こりません。

それでも、現在のシステムの動作に関する詳細な知識があったことと、11年の人生でそれほど多くのいぼを開発していなかった比較的きれいなコードであったことを除いて、書き直したかどうかはわかりません。


0

最初からやり直す必要があるポイントを決定するには、現在のプロジェクトを継続する価値が最初からやり直す価値に満たない場所を見つける必要があります。

これが非常に難しい理由は、実際に開始するまで、新しいプロジェクトでのチームの開発速度を正確に見積もることです。とはいえ、新しいプロジェクトでの開発速度の非常に保守的な見積もりを使用すると、プロジェクトが投資に見合う価値をもたらすと見積もられた場合、新たに始めるためのビジネスケースがあります。


0

私のメトリックでは、書き換えを正当化するために2つの条件を満たす必要があります。

  1. 書き直した後、新機能の記述が簡単になります。
  2. 書き換えには、現在の新しい機能を追加するよりも短いか、同じ時間がかかります。

その場合でも、書き換えの範囲を制限する必要があります。例として、モジュール性を知らないCプログラマーの考え方で、C ++で書かれた会社にいくつかのレガシーソフトウェアがありました。最終結果は、複数のクラスとDLLにまたがる有限状態マシンの形式のspeghettiコードでした。コードに組み込まれた前提条件とは非常に異なる新しい要件があり、顧客に対する同社の特許取得済みの付加価値の一部になる予定でした。

他の機能を実装するコードで時間を費やした後、いくつかのswitchステートメントのどれを変更する必要があるかなどを理解するのにどれくらい時間がかかるかについて、本当に良いアイデアがありました。巨大な有限状態マシン。既存のコードを拡張するよりも時間がかかりません。以前は3つであったDLLを1つに統合し、重要な新機能をより簡単に実行できるようになり、新しい機能を追加しやすくする、よりオブジェクト指向の構造を提供できました。

書き換えを必要とするライブラリを使用する他の3つのアプリケーションがあったため、これらのプログラムを完全に書き換える必要はありませんでした。範囲はライブラリと、ライブラリを既存のソフトウェアにバインドするために必要なものに限定されていました。私の見積りははるかに外れていなかったし、仕事はそれ自体に支払われた。再設計後まもなく、新しい機能を追加する必要がありました。古い構造で1週間かかったのは、新しい構造で1日だけでした。


0

OPはプロジェクトの範囲を示していませんが、私が取った主な手がかりは、「古い[libs]を使用して古い[言語/方言]で書かれた」ことでした。実際、私がこれまで市場に出回っていたほとんどのプロジェクトは、コンパイラ/インタープリター/オペレーティングシステムの更新に対応することがコードベースを維持する上で重要なタスクであることを最終的に認識しています。

要するに、私は最初にライブラリの更新を優先して、段階的に再書き込みを計画します。途中で他の最適化をこっそりすることができるかもしれませんが、いくつかの変更を後のフェーズに延期することを計画しているという事実は、スケジュールを維持して「スタック」を回避する素晴らしい方法です。


0

既存のコードベースを捨てるだけの仮想シナリオを想像できます(バッキーボールの重量と体積がゼロで、見落とされた機能やバグを追加するために数週間または数か月の生産性を失っても気にしない仮想的な状況)システムへの修正、およびシステムが非常に些細で組織によって嫌われている場合、10分でサーバーのすべてと軍隊をnotepad ++とネットブックに置き換え、全員の生産性と道徳を高めることができます)

ほぼすべての実際のシナリオでは、リファクタリングを実施することをお勧めします。^ _ ^。文書化されていない法的要件やビジネス要件がポップアップし始め、土壇場で物事をハッキングすると土壇場で書き直しに隠れた、予想外のコストが多すぎる傾向があります。

==より良いものを得るための適切なリファクタリング、およびスタッフ==

通常の古いインクリメンタルアプローチを使用してレガシーコードをリファクタリングし、

  1. UMLに変換する機会があり、どんなちょっと変わったアーキテクチャがあるかを文書化してください。
  2. バージョン管理を行っている場合は、コードチャーンレポートを生成し、どのファイルとファイルセクションが最も頻繁に変更されているかを調べてください。これらはおそらく最初に対処する領域になる可能性があるため、これらをメモします。
  3. コードを変更する前に、必ずテストカバレッジを追加してください((いフルスタック機能テストでも可能です)。大きくて厄介な手続き型コード抽出ロジックを扱う場合は、合理的な名前のメソッドまたは関数に変更し、可能であれば新しいメソッドを検証するテストケースを追加します。あなたがしなければならない神の恐ろしいハックを作り、可能であればマージン幅やタイトルのような一般的に微調整されたものであれば変更をパラメータ化し、次回更新するのが少し簡単になるようにします。
  4. アダプターパターンを使用して、論理的に名前が付けられたクラスとメソッドのラグの下にあるレガシーコードの隠れたビットを隠してください。レガシーコードの背後に隠した素敵で小さなクリーンなメソッドとクラスの背後-納屋で変形した殺人ゾンビの元家族を維持し、日々の邪魔をしないようにする素敵な家族のように農場。。。通常は。
  5. コードのセクションを削ってクリーンアップし続けると、テストカバレッジが向上します。これで、必要に応じて/必要に応じて、さらに深く掘り下げて、さらに多くのコードを「書き直し」、自信を深めることができます。
  6. コードベースを改善し続けるために、繰り返し、または追加のリファクタリングアプローチを適用します。

抽象化による分岐

  1. 削除するコードのトラブルスポットを定義します(永続化レイヤー、pdfジェネレーター、請求書集計メカニズム、ウィジェットジェネレーターなど)。
  2. 一般的な動作とともに、この機能を対象とするコードベースに対していくつかの機能テストケース(自動または手動ですが、自動化されていることを知っています)を実行(必要に応じて記述)します。
  3. そのコンポーネントに関連するロジックを既存のソースベースから適切なインターフェースを持つクラスに抽出します。
  4. すべてのコードが新しいインターフェイスを使用して、以前はコード全体にランダムに分散されていたアクティビティXを実行していることを確認します(コードベースのGrep、新しいクラスへのトレースの追加、呼び出し元のページの確認など)。単一のファイルを変更することで、使用する実装を制御できます(オブジェクトレジストリ、ファクトリクラス、IActivityXClass = Settings.AcitivtyXImplementer();)
  5. 新しいクラスにすべてのアクティビティXをスローして、すべてがまだ機能していることを確認する機能テストケースを再実行します。
  6. 可能な場合は、新しいアクティビティXラッパークラスの周囲で単体テストを作成します。
  7. 従来のクラスと同じインターフェースに準拠する従来の実装よりも非常識なスパゲッティロジックの少ない新しいクラスを実装します。
  8. 新しいクラスがレガシークラス用に作成したユニットテストに合格することを確認します。
  9. 古いクラスの代わりに新しいクラスを使用するようにレジストリ/ファクトリメソッド/その他を変更してコードを更新します。
  10. 機能テストがまだパスしていることを確認してください。

オープンクローズド原則と共通のビジネスロジック/永続層

ある程度まで、プレゼンテーション、ビジネス、および永続レイヤーを分離し、レガシーソリューションと完全に下位互換性のある新しいアプリを作成するか、少なくともレガシーソリューションによって入力されたデータを処理することができます。おそらくこのアプローチはお勧めしませんが、時間/スケジュール/リソース/必要な新機能の妥当な妥協案である場合があります。

  • 少なくともプレゼンテーション層をビジネス層と永続化層から分離します。
  • 同じ共通のビジネス層と永続化層を使用する新しいUIとより優れたプレゼンテーション層を実装します。
  • 新しいuiで作成されたデータが古いuiを壊さないことを確認します。(新しいツールのユーザーが古いツールのユーザーを中断した場合、お湯になります)。完全な後方互換性を目指している場合は、すべてを同じ永続層に保存する必要があります。新しいツールへの上位互換性が必要な場合は、新しいデータベースと新しいテーブルまたは拡張テーブルを使用して、レガシーシステムにないデータを追跡します。
  • 新しい機能と永続化レイヤーのニーズについては、新しいテーブルとメソッドを追加して、既存のレガシーロジックを変更したり、既存のテーブルに列制約を追加したりしないでください。たとえば、雇用主の緊急連絡先の追跡を開始する必要があり、他のフィールドが既存の従業員テーブルを変更しない場合(レガシーデータがそのテーブルについてどのような仮定を立てているかわかりません)、拡張テーブルemployee_ext id、employee_id、emergency_contact_idなどを追加します
  • ユーザーを新しいシステムにゆっくり移行します。可能であれば、レガシーシステムを読み取り専用モードにするか、X日以降は利用できなくなることをユーザーに伝える警告を追加します。
  • 新しいUIで、優先度の低い機能またはビジネス要件を実装する
  • ロールオーバーユーザーベース。
  • ビジネスロジックと永続化レイヤーのユーザーの他のリファクタリング手法のクリーンアップを続けます。

0

リファクタリングとリライトの分野には3番目のカテゴリがあると思います...そして、それはあなたの言語バージョン、コンパイラ、およびライブラリを更新しています...時々、最新のコーディング技術を採用するだけでも大きな利点があります。

たとえば、C#を例にとると、v7コードはv2よりもずっとクリーンで安全で簡潔です。エルビスやnull合体演算子のようなものが非常に役立ちます。

コンパイラの切り替えは、古いコードに新しい命を吹き込むこともあります。作業や実装を容易にする新しいライブラリもあるかもしれません...ネットワークは、実装が困難なスペクトルの優れた例です。

また、組み込みLinuxシステム...新しいツールのインストールを検討してください。svnからgitに切り替えてください。または、Viをシステムなどに追加します。

常にリファクタリング対リライトである必要はありません。アーキテクチャはおそらく改善が必要ですが、機能します...コードの書き方などを考える必要があるだけかもしれません。


-2

レガシーアプリを書き換えている人を見たことはないと思います。

起こることは、人々が前の世代と共通のいくつかの機能を持っている異なるアーキテクチャ、技術などで全く新しいアプリを書いているということです。また、アプリ2.0と呼ばれますが、実際には元のアプリと共通するものはほとんどありません。

ただし、これは、機能パリティを実現しようとしているという意味で、実際には元の「書き換え」ではありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.