web-dev-qa-db-ja.com

書き換えはいつ適切ですか?

私は、プログラミング中にプログラミングを学んでいた科学者によって完全に記述されたプロジェクトを実施しています。これはC++の約200,000行であり、ほとんどすべての変数がグローバル変数です(2,000を超えるグローバル変数)。彼はプロジェクトを書いている途中でローカル変数について知ったと思います。いくつかのローカル変数名は、ほとんど常にx、xx、i、ii、j、jj、M、またはその他の1文字の名前です。このプログラムは、セグメンテーション違反が発生する傾向があり、valgrindを実行すると、メモリ破壊のほぼ1000インスタンスが明らかになります。それは未定義の動作に完全に依存しており、CentOS 7でのみ正しい結果を生成し、Ubuntuは完全に異なる不正な結果(科学的コード)を生成します。原作者以外は完全に解読できません。私たちは今、ユニークな立場にあり、会社がこれまでに製品ソフトウェアを書いたことがない誰かが書いたこの1つのソフトウェアにすべてを賭けるつもりです。このコードベースで数か月作業した後、ほとんどすべての行に困惑し、最も基本的な機能の実装には信じられないほど長い時間がかかるため、ここには極端なバス要因があります。この会社の他の開発者は、このコードに触れたがりません。これは私が今まで見た中で最悪のコードです。新入生のCSの学生であっても、このようなコードは見たことがありません。

この状況を考えると、これは「燃え尽きて、ゼロから始める」のに適切なケースですか?これを保守可能なコードベースにするための良い戦略は何ですか?このコードは、研究が進むにつれて頻繁に更新する必要があるため、コードをフリーズすることはできません。

明確にするために、このプロジェクトはまだ本番環境で使用されていません。これまでのところ完全に実証されており、今年の夏に生産に使用されます。

これがどのように見えるか知りたい人は、関数は次のようになります。

void doSomething(void) {
  sideEffect1();
  sideEffect2();
  sideEffect3();
  ...
  sideEffect145();
}

void sideEffect1(void) {
  if (globalVar1) {
    return;
  }
  anotherSideEffect1();
  if (globalVar2) {
    globalVar1 = globalVar2 + 1;  
  }
  ... hundreds of lines later
}
7
Kyle

できれば実行可能なテストとして、完全で詳細かつ包括的な要件のセットがありますか?

私は推測します:いいえ作家はおそらくそれらをまだ発見していないので...

そのような場合、それを焼き尽くして再構築することが比較可能であることさえ保証されません。すでに述べたように、未定義の動作を使用しているため、コードが期待どおりに動作するかどうかさえ確信できません。言うまでもなく、コードベース全体に広がるロジックのうなり声のために、アルゴリズム自体が何であるかに当惑しています。

代わりに、一連のテストを開発することから始めます。数か月分の入出力を取得して、データが一致することを確認するだけでも、.

少なくとも、これにより、コードを中断したかどうかを%で確認できます。

リファクタリング

まず、1つの関数、1つの変数、または1つのクラスを選択します。それを改善するために何ができるかを見てください。

  • その名前を改善します。関数/変数/クラスが何を/表すかを理解します。
  • 変数をより狭いスコープにプルします。
  • 数行の順次コードを見つけ、それを独自の名前付き関数に入れます。
  • 関数/変数をクラスにラップする
  • クラスを分割して結束力を高め、懸念事項間の境界を導入します。
  • 明確に定義されたセマンティクスを使用して、未定義の動作を言い換えます。
  • など...コードベースを読んで理解する能力を向上させる小さな変更。

テストを頻繁に実行して、明らかに破損しているものを見つけます。


このバディプログラミングをその科学者と一緒に行うのが最善です。このようにして、コードベースを改善し、コードをより適切に記述する方法について科学者をトレーニングし、科学者にそれぞれの意味/機能について入力してもらうことができます。

必須のコードレビューを伴うプルリクエストを作成する場合にも役立ちます。これにより、明らかに悪いコードにプッシュバックできるようになり、状況が悪化しなくなります。

8
Kain0_0

私たちは今、ユニークな立場にあり、会社がこれまでに製品ソフトウェアを書いたことがない誰かが書いたこの1つのソフトウェアにすべてを賭けるつもりです。

これは大きなリスクです。

そのため、私はimmediate問題に焦点を当てます(リファクタリングの怒りを防ぐため):

  • 複数のオペレーティングシステムで実行されないことが当面の問題ですか?
  • プログラムはすべての状況で信頼できませんか、それとも特定の方法で確実に使用でき、その方法で使用すると常に良い結果が得られますか?
  • 最も一般的な変更に合わせてコードを調整するのにどのくらいの時間がかかりますか?それを改善するために行うことができる最小限の変更は何ですか?

言い換えれば、壊れていないものを修正せず、最小限の実行可能な製品を作ることに集中してください。

この焦点は、プログラムをできるだけ早く稼働させるのに役立ちます。

次に、おそらく並行して、元の作者と密接に協力して関数と変数の名前を変更します。主にドメインとソリューションを学び、理解すること。名前以外は変更しないでください。目標は理解することです。

名前の変更後、適切なリファクタリングを試行できます。

3
Erno

あなたがそれを焼き尽くして、ROMスクラッチを開始するなら、私はあなたが機能しない混乱で終わることを保証できます。あなたの最良のチャンスは、少しマゾヒスティックな連勝を持つ優秀な専門家を雇って、このコードを改善するために彼にお金を払うことです。安くはありません。

0
gnasher729