web-dev-qa-db-ja.com

BIG Rewriteの答えはいつですか?

Big Rewritesに関する質問 を読むだけで、自分が回答したかった質問を思い出しました。

古いJavaで記述された恐ろしいプロジェクトがStruts 1.0を使用して受け継がれています。関係に一貫性がないか、関係がまったくないか、主キーまたはフィールドが主キーではないが、一意ではないテーブルさえあります。どういうわけか、ほとんどのアプリは「動作する」だけです。ほとんどのページは再利用され(貼り付けられたコードをコピー)、ハードコードされます。これまでプロジェクトに取り組んだことのある人なら誰でも、それを何らかの形で呪いました。

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

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

288
Jonn

申し訳ありませんが、これは長くなるでしょうが、それは複数の書き換えプロジェクトでの建築家と開発者の両方としての個人的な経験に基づいています。

次の条件では、何らかの書き換えを検討する必要があります。その後、どちらを行うかを決める方法についてお話します。

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

これらのことはかなり自明です。完全なリライトと増分リビルドのどちらを決定するかは主観的であり、したがってより政治的に課せられます。私が確信をもって言えることは、それを決してと断定的に述べることは、良いアイデアは間違っているということです。

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

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

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

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

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

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

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

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

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

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

次の場合、書き換えが答えになることがあります。

  • 別の言語またはプラットフォームに切り替えます。
  • フレームワーク/外部コンポーネントを切り替えます。
  • 既存のコードベースはもう保守できません。

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

112
Toon Krijthe

次の場合は、書き換えの時間です。

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

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

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

プロジェクトのアーキテクチャーに根本的な変更が必要な場合は、再起動するのにおそらくです。

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

ただし、公正な警告に注意してください。現在のプロジェクトでは、ビジネスルールがテストされ、無数の人手による実際の使用で洗練されています。これは、ゼロから始めたプロジェクトには当てはまりません。

時間枠や直感は、このような抜本的な対策の適切な尺度とは思えません。この一連の行動に参加するには、明確防御可能、およびよく理解されているの理由が必要です。

17
Dan McGrath

私はクラミイの答えとジョエルの意見には同意しますが、書き換えを行うことが適切な場合があります。長寿命のアプリケーション(10〜20年以上と言っています)では、時間の経過とともにメンテナンスがますます高価になります。これは、迅速なメンテナンスパッチのために元のアーキテクチャが犠牲になっているため、コードがますますスパゲッティになっているためです。また、古い技術の開発者は、より希少で高価になります。最後に、ハードウェアは古くなり始め、古いアプリケーションを実行するための新しいハードウェア、オペレーティングシステム、フレームワークなどを見つけることはますます難しくなります。また、ビジネスは進化し、ほとんどの場合、古いシステムは組織のビジネスニーズを満たすことができず、真新しいシステムでも対応できなくなります。

そのため、継続的なメンテナンスコストのすべてと、新しいシステムがビジネスにもたらす潜在的なメリットを、最初から物を書き直すコストと比較検討する必要があります。書き換えのコストについての見積もりではvery悲観的になる。ほとんどの場合、コストがかかり、思ったよりも時間がかかります。

12
RationalGeek

やめる!書き換えはほぼ never 答えです。多くの場合、リファクタリングの方が適しています。


もちろん、書き換えが正当化されるのは回あります:

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

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

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

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

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

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

また、書き換えを行うと、新しいコードベースに多くの新しいバグや混乱がもたらされることが保証されていることにも注意してください。

11
Kramii

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

enter image description here

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

10

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

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

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

これは、書き換えが必要なケースの1つであるように見えます。この巨大なものを理解し、このビジネスに特化した機能のビットを引き出し、既存のシステムに追加する必要のある部分を書き直さなければならないようです。これが完了すると、既存のシステムがこの新しいセクターをサポートできるようになり、この獣は悲惨な状態から抜け出すことができます。そうでなければ、正気を失うことになります。

8
Jay

私は、Y2Kを処理するようにアップグレードされたいくつかのDOSアプリケーションがあり、Windows 16ビットアプリとして書き直され、さらに1つの「小さな」機能を備えた32ビットアプリとして書き直された(最終的には1人の顧客)が全体の構造に影響を与えました。

16ビットコードを32に移動することは、1か月で1人で行うことができたかもしれませんが、NOOOOOOOOO、それを書き直す必要がありました。このことは他の産業に適応することができ、開始する前でも完全な仕様と疑似コードを持っているでしょう。仕様は作成されましたが、実際のコードを書くのに時間がかかりませんでした。それは遅くリリースされ、16ビットの「最初の」よりも多くのバグが含まれていました(v.3.0にあり、ついに誰かが新しいバグを報告することなくほぼ1週間で完了できるようになりました)。

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

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

7
JeffO

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

2年間にわたって、私たちは拡張作業と一緒にビットやピースのリファクタリングに取り組みました。私たちは常に「硬化」タスクをプロジェクト計画に取り入れました。うまく機能しなかった特定の領域に焦点を当てることで、費用を最大限に活用できました。うまくいったものは私たちが一人にした。また、この作業が通常の開発の過程で行われ、リリースされたことも重要です。大きな書き換えの問題は、1年以上続いてから、戻ってくるまでにすべてのものが変更され、いくつかの厄介なバグが解消され、ROIが失われます。

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

5
Bill Leeper

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

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

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

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

私は、機能を複製し、カスタマイズして業界の他の人々に販売できる製品を作るために雇われました。問題は、これが過去10年間にすべてのビジネスニーズを満たすために作成されたということです(とにかく、そのうちの5から6シグマと言っていいでしょう)。

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

5
Incognito

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

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

4
user21007

Joel Spolskyはこれに関して優れた記事を持っています: 絶対にしてはいけないこと、パートI

あなたが言うことができるタイトルから、それはちょっと一方的なものです(彼はなぜコードをスローしてはいけないのかについて話します)IMO、それには多くの真実があります、私は最近いくつかの開発者が言ったExcelの25周年でchannel9ビデオを見ました、どのように今日でもソースを調べた場合、リビジョンを確認すると、20年前に作成されたExcelのコードに戻ることになります。

100%確信することはできません(Netscapeでも間違いがある場合(Joels記事から))[〜#〜] i [〜#〜] Joelの記事は神から送られたものだと感じました。悲観的になる可能性があり、コードを捨てるのが大好きです。いつでも2度書いた方が良いと思いますが、これが実現したのは、たった今コストがかかるだけです。

具体的な答えを与えるために、私はコストと値の完全な比較を行う必要があります分析と言います。

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

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

4
gideon

「Xに行くならここから始めない」という古典的なジョークがあります。

私は一度仕事に就きましたが、雇用主の主な動機は、才能を持ってビジネスクリティカルなアプリの長期に渡る書き換えを開始することでした。私が尋ねることができなかった質問は、なぜあなたはなぜ最初にこのような状況に終わったのですか?原因が原因であったかどうか、それは危険信号であるはずでした

  • 獣を維持し、段階的にリファクタリングするための機能を追加するためのあまりにも多くの圧力、

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

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

または何でも、そしてこれは問題が耐え難いレベルに達するまで衰退を引き起こします。

したがって、大規模な書き換えはおそらく非常に悪い考えであるという点で、ジョエルに同意します-大規模な書き換えが必要と思われる理由の背後にある根本的な理由がすべて明確である場合を除きますを処理すると、やがて問題を繰り返す可能性が高くなります。

2
Julia Hayward

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

代わりに、書き換えが頻繁に発生し、管理の心配が軽減されます。

  • すべてが.NETにある必要があります。
  • 開発者は私たちのコードは駄目だと言っています
  • 技術的に遅れている、
  • システムをサポートするためのリソースを見つけることができません。
  • 10年経ちましたので、そろそろ時間です。

これらの心配のほとんどは実現せず、実現したとしても対処できます。しかし、最後の1つは最悪です。それは本質的にです:私たちは理由がありません。

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

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

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

2
Mario T. Lanza

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

2
Craig

Joelによると、大きな書き換えは1つの最悪の戦略的ミスです。

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

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

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

2
user3287

決して、常にリファクタリングします-真実は、コードがあなたによって書かれたかどうかです-あなたはこれ以上何もできません。

テクノロジーを変更したい場合を除いて、コードには構造がありません(私はかなり前にいくつかのPHP Webサイトで作成者がinclude/class/functionではなくspahgettiをコピーして貼り付けた)で見ました)または、ひどく書かれた他の人から何かを引き継いだ。

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

2
Slawek

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

「完全に新しい」:書き換えを計画しているが同じプラットフォームを使用する場合は、リファクタリングと賢明な再構築がほぼ間違いなく優れたソリューションです。ここで使用されている「プラットフォーム」はややあいまいです。言語、およびおそらくOS(LinuxからWindowsへの拡張、またはその逆が頭に浮かぶ)を含めることを検討してください。

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

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

1
Anon

さて、私は既存のコードベースを捨てるだけの架空のシナリオを想像できます(バッキーボールの重量と体積がゼロであり、見過ごされている機能やバグを追加するために何週間または何ヶ月も生産性を失ってもかまわないという架空の状況。システムへの修正、およびシステムが非常に些細で組織に嫌われている場所で、サーバー全体とノートブックをノートパッド++とネットブックで10分で置き換えることができ、全員の生産性とモラル全体を向上させることができます。)

ほとんどすべての現実のシナリオでは、適切なリファクタリングをお勧めします。 ^ _ ^。文書化されていない法的要件およびビジネス要件がポップアップし始め、ギリギリの事柄がギリギリにハッキングされると、書き直しに隠れて予想外のコストがかかりすぎる傾向があります。

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

通常の古いインクリメンタルアプローチによるレガシーコードのリファクタリング

  1. UMLに変換する機会があれば、そこにどんな危険なアーキテクチャがあるかを文書化してください。
  2. バージョン管理を行っている場合は、コードチャーンレポートを生成し、最も頻繁に変更されているファイルとファイルセクションを特定します。これらはおそらく最初に処理する領域になるため、これらを書き留めてください。
  3. コードを変更する前に、必ずいくつかのテストカバレッジを追加してみてください(醜いフルスタック機能テストでも十分です)。大きな乱雑な手続き型コード抽出ロジックを処理する場合は、適切な名前のメソッドまたは関数に変更し、可能であれば、新しいメソッドを検証するテストケースを追加します。神のひどいハックを作り、可能であればマージンの幅やタイトルのように微調整したものをパラメータ化して、次回の更新が少し簡単になるようにします。
  4. アダプターパターンを使用して、論理的に名前が付けられたクラスとメソッドのラグの下にレガシーコードの節のあるビットを隠すことを回避します。これにより、あなたと他の開発者が実行するほとんどの一般的なタスクについて、背後で起こっている恐ろしいビットについて心配する必要がなくなります。旧式のコードを背後に隠した素敵な小さなきれいなメソッドとクラスの背後に背を向けます-変形した殺人ゾンビの元の家族を納屋に置き、日々の日常生活を損なうことがない素敵な家族のように農場。 。 。通常は。
  5. コードのセクションを削ってクリーンアップし続けると、テストカバレッジが向上し続けます。これで、必要に応じて/ますます信頼を増して、さらに深く掘り下げ、さらに多くのコードを「書き換え」ることができます。
  6. コードベースの改善を続けるには、繰り返し、または追加のリファクタリングアプローチを適用します。

抽象化による分岐

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

オープンクローズの原則と共通のビジネスロジック/永続化レイヤー

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

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

リファクタリングとリライトの領域には3つ目のカテゴリがあると思います...そして、それは言語バージョン、コンパイラ、およびライブラリを更新しています...時々、最新のコーディング手法を採用するだけで大​​きなメリットが得られる場合があります。

C#を例にとると、v7のコードはv2よりもずっとクリーンで安全で簡潔です。Elvisやnullの合体演算子などは、非常に便利です。

コンパイラの切り替えも、古いコードに新しい命を吹き込むかもしれません。ですから、作業や実装を簡単にする新しいライブラリーがあるかもしれません...ネットワーキングは、さまざまな実装の困難さの好例です。

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

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

0
visc

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

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

0
Nobody

私の測定基準では、書き換えを正当化するために2つの条件を満たす必要があります。

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

それでも、書き換えの範囲を制限する必要があります。たとえば、ある企業では、モジュール性について知らないCプログラマを念頭に、C++で記述されたレガシーソフトウェアを使用していました。最終結果は、複数のクラスとDLLにまたがる有限状態マシンの形のspeghettiコードでした。コードに組み込まれた仮定とは大きく異なる新しい要件があり、同社の特許を取得した顧客への付加価値の一部となる予定でした。

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

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

0
Berin Loritsch

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

要するに、私は段階的に書き換えを計画し、最初にlibsの更新を優先します。途中で他の最適化をこっそりと実行できるかもしれませんが、一部の変更を後のフェーズに延期することを計画しているという事実は、スケジュールを維持し、「行き詰まる」のを回避するための優れた方法です。

0
MarkHu