タグ付けされた質問 「refactoring」

リファクタリングは、既存のコード本体を再構築し、外部の動作を変更せずに内部構造を変更するための統制のとれた手法です。

7
コードを一般的なコードにリファクタリングする方法は?
バックグラウンド 現在進行中のC#プロジェクトに取り組んでいます。私はC#プログラマではなく、主にC ++プログラマです。そのため、基本的に簡単でリファクタリングするタスクが割り当てられました。 コードはめちゃくちゃです。それは巨大なプロジェクトです。お客様が新機能とバグ修正を含む頻繁なリリースを要求したため、他のすべての開発者はコーディング中にブルートフォースアプローチをとることを余儀なくされました。コードはメンテナンスが非常に難しく、他のすべての開発者はそれに同意します。 私は彼らがそれを正しくしたかどうかを議論するためにここにいるのではありません。私はリファクタリングしているので、リファクタリングされたコードが複雑に思えるので、正しい方法でそれをやっているかどうか疑問に思っています!これが簡単な例としての私の仕事です。 問題 6つのクラスがありますA、B、C、D、EとF。すべてのクラスには関数がありますExecJob()。6つの実装はすべて非常に似ています。基本的に、最初A::ExecJob()は書かれました。次に、のB::ExecJob()copy-paste-modificationによって実装されたわずかに異なるバージョンが必要でしたA::ExecJob()。別のわずかに異なるバージョンが必要になったとき、C::ExecJob()書かれたなど。6つの実装すべてに共通のコードがあり、次にいくつかの異なるコード行があり、さらにいくつかの共通コードがあります。実装の簡単な例を次に示します。 A::ExecJob() { S1; S2; S3; S4; S5; } B::ExecJob() { S1; S3; S4; S5; } C::ExecJob() { S1; S3; S4; } SNまったく同じ文のグループはどこにありますか。 それらを共通にするために、別のクラスを作成し、関数内の共通コードを移動しました。パラメータを使用して、実行するステートメントのグループを制御します。 Base::CommonTask(param) { S1; if (param.s2) S2; S3; S4; if (param.s5) S5; } A::ExecJob() // A inherits Base { param.s2 = …

7
流なコーダーがグッドプラクティスを無視する場合、彼の流fluさは彼に反していないでしょうか?[閉まっている]
閉じた。この質問は意見に基づいています。現在、回答を受け付けていません。 この質問を改善したいですか?この投稿を編集して事実と引用で答えられるように質問を更新してください。 4年前に閉鎖されました。 私はかなり大きくてバグのあるアプリケーションに取り組んでいます-それが書かれている方法のために(詳細は省きますが、あなたが考えることができるほとんどの分野でルールに違反します)、大きなリファクタリングなしでそれを開発することはほとんど不可能です。 アプリの重要な部分は、インターン、n00bsなどによって作成されました。しかし、Master Developerの階級にプログラマーもいました。そして、謙虚に、彼が残したコードも、おそらくは別の方法で疑わしいです。 確かに、彼のコードはほとんどの場合、仕事を終わらせる傾向がありますが、通常はわかりにくく、車輪を再発明します(たとえば、通常のSQL dbバックアップを実現する大きなカスタムメソッド)など。基本的に、不必要な混乱と多くのオーバーエンジニアリング そして、他の資質を伴わない場合、高度に熟練したコーダーであること(私は意図的に「開発者」という単語をより広いスキルのセットを示すと仮定して使用しません)が実際には有毒であると考えるようになりました。 それが真実だと仮定すると、私が考えることができるいくつかの理由は次のとおりです。 簡単にコーディングしている場合、ライブラリや既存の機能などを使用せずに、その場で独自のソリューションを簡単にスナップアウトできる(または実際には短期的には)と感じます。 複雑なプログラムのメンタルイメージを簡単に維持できる十分な経験がある場合、それをモジュール、レイヤーなどに分割する傾向は低くなります。 私のポイントは、流なコーダーが偶然悪い開発者である場合、流fluさは後者を補うだけでなく、実際にはむしろより多くの害をもたらすということです。 あなたはそれをどう思いますか?それは本当ですか?

5
リファクタリングするコードのテストを書くのはなぜですか?
私は巨大なレガシーコードクラスをリファクタリングしています。リファクタリング(私は推測する)はこれを支持します: レガシークラスのテストを書く クラスから一体をリファクタリングする 問題:クラスをリファクタリングしたら、ステップ1のテストを変更する必要があります。たとえば、以前は従来のメソッドにあったものが、代わりに別のクラスになる場合があります。1つの方法でしたが、現在はいくつかの方法である場合があります。レガシークラスの全体像が何か新しいものに抹消される可能性があるため、ステップ1で記述するテストはほとんど無効になります。本質的に、ステップ3を追加します。テストを大量に書き換えます。 リファクタリングの前にテストを書く目的は何ですか?それは自分自身のためにより多くの作品を作成する学術的な運動のように聞こえます。現在、このメソッドのテストを書いていますが、物事をテストする方法と、従来のメソッドがどのように機能するかについて詳しく学んでいます。レガシーコード自体を読むだけでこれを学ぶことができますが、テストを書くことは、その中に鼻をこすりつけることと、別のテストでこの一時的な知識を文書化することにほとんど似ています。したがって、この方法では、コードが何をしているのかを学ぶ以外にほとんど選択肢がありません。私はここで一時的なことを言いました。なぜなら、コードを完全にリファクタリングし、ドキュメントとテストのすべてがかなりの部分で無効になるためです。ただし、私の知識は残り、リファクタリングの新鮮さを保つことができます。 それがリファクタリングの前にテストを書く本当の理由ですか?コードをよりよく理解するのに役立ちますか?別の理由があります! 説明してください! 注意: この投稿があります:完全なリファクタリングの時間がないときにレガシーコードのテストを書くことは理にかなっていますか?しかし、「リファクタリングの前にテストを書く」と言いますが、「なぜ」とは言いません。

7
ほとんどが1つの正規表現で構成される大きな関数をリファクタリングする必要がありますか?[閉まっている]
閉じた。この質問は意見に基づいています。現在、回答を受け付けていません。 この質問を改善したいですか?この投稿を編集して事実と引用で答えられるように質問を更新してください。 5年前に閉鎖されました。 約100行にわたる関数を作成しました。それを聞いて、あなたはおそらく私に単一の責任について教えて、私にリファクタリングを促すように誘惑されるでしょう。これは私の本能でもありますが、問題は次のとおりです。関数は 1つのことを行います。複雑な文字列操作を実行し、関数の本体は主に1つの冗長な正規表現で構成され、文書化された多くの行に分割されます。正規表現を複数の関数に分割すると、実際に言語を切り替えているため、実際に読みやすさが失われ、正規表現が提供する一部の機能を利用できなくなるためです。ここに私の質問があります: 正規表現を使用した文字列操作に関しては、大きな関数本体は依然としてアンチパターンですか?名前付きキャプチャグループは、機能と非常に似た目的を果たしているようです。ところで、正規表現を通るすべてのフローのテストがあります。

2
コンストラクタの代わりにファクトリメソッドを使用する必要がありました。それを変更しても下位互換性はありますか?
問題 ファイルからデータを読み取るためのメソッドDataSourceを提供するクラスReadData(および他のクラスもありますが、物事をシンプルにしましょう)があるとし.mdbます。 var source = new DataSource("myFile.mdb"); var data = source.ReadData(); 数年後、データソースとして.xmlファイルに加えて.mdbファイルもサポートできるようにしたいと決めました。「データの読み取り」の実装は.xml、.mdbファイルとファイルでまったく異なります。したがって、システムをゼロから設計する場合、次のように定義します。 abstract class DataSource { abstract Data ReadData(); static DataSource OpenDataSource(string fileName) { // return MdbDataSource or XmlDataSource, as appropriate } } class MdbDataSource : DataSource { override Data ReadData() { /* implementation 1 */ } } class XmlDataSource …

6
「コード改善」の優先度と重大度を判断する方法は?
バグ追跡システムには「優先度」フィールドと「重大度」フィールドがあります。重大度は「ユーザーへの影響」、優先度は「製品への影響」として定義します。 私の質問は、「コード改善」タスクを重大度と優先度に分類する方法についてです。改善によって動作が変更されることはなく、「より良いコード」になると仮定します。全体的な長期的なメンテナンスの改善が見込まれますが、定量化するのは困難です。 優先度と重大度の定義を使用すると、予測が困難な長期的な利点を図に導入しない限り、コードの改善により両方の値が最も低くなります。したがって、コードの改善は簡単な作業ではなく、決して試みるべきではないことを意味します。 ただし、コードを絶えず改善してリファクタリングすることは非常に重要だと思います。 ソフトウェア開発自体は継続的な学習プロセスであり、コードを改善しなければ、それを上達させることはできません。 チームはコードを誇りに思うべきです。 今後のメンテナンスにかかる時間は短くなり、長期的には大幅な節約になります。 または、そのようなタスクは決して作成されるべきではなく、そのような改善は「オンデマンド」でのみ、「バグに関連する場合」に実行されると思いますか?それがバグに関連しているとしても、それがコードレビューの議論ポイントではないでしょうか?例えば、「なぜあなたはこの構造の劇的な変更をしたのですか?」

10
大きな変更を提案する/インターンとして書き直す[終了]
閉まっている。この質問はトピック外です。現在、回答を受け付けていません。 この質問を改善したいですか? 質問を更新して、 Software Engineering Stack Exchangeのトピックになるようにします。 4年前に閉鎖されました。 コンテキスト: それは内部プロジェクトです(多くの人が使用するとは思わない) 古いです 私たちはそれを更新しています 問題: mvcフレームワークを悪用します(モデルの使用、ビューでのビジネスロジックなど) 求められていることは小さいですが、凝集度が低いため、2つのオプションがあります。 物事をやり続ける 大量のコードを移動したり、コードを書き直したりする ソリューション(私が見る): 引き続き作業し、ベストプラクティスを無視して、すぐに行われ、リファクタリング/リライトによって新しいバグを導入しないことを支持する リファクタリング/書き換え 私の質問は本当にそうだと思います:このプロジェクトに大きな変更を加えたい場合、誰をin辱せずにそれを提案するにはどうすればよいですか?それとも、それが時々(比means的な)ダクトテープを意味していても、単純に流れに行く方が良いでしょうか?

10
コピー/貼り付けパターンを修正する方法は?
私が働いている場所では、人々(コンサルタント)はできるだけ早く機能をリリースするよう迫られています。そのため、物事を正しい方法で行う方法を考えたり、何かを壊したくないために時間をかけすぎたりする代わりに、コードは異なるモジュールからコピーされ、修正されます。 コードベースは会社全体に公開されているため、これを防ぐのは簡単ではありません。多くの人々がこれに取り組んでいます。 混乱がすでにあるので、あまりにも壊さずにそれらの冗長性を削除する最良の方法は何ですか?

11
他の作業中に既存の欠陥を修正する必要がありますか?
難問:新機能の作業中または欠陥の修正中に、コードに古い問題が見つかります。あなたは何をするべきか?それを修正し、コードの動作を変更する危険を冒してください。それは、これまでに何らかの欠陥によってうまく機能しているか、あるいは欠陥が検出されていないか、報告する時間がないかのどちらかです。そのままにして、問題が原因でコードを後で操作しにくくする必要がありますか?問題を修正すると、元のタスクの時間が増えるだけで、強制的に回帰テストが行​​われます。仕事に感謝する人はほとんどいません。しかし、それを修正することは、どういうわけか正しいようです。問題の少ないコードは、リファクタリングやビルドが簡単です。 Webアプリケーションの近代化に取り組んでいるとき、私はこの状況に何度も気づきました。これらの古いバグに取り組んでいるとき、自分が強迫観念を持っているのか、それとも名誉あるのかはわかりません。これらの状況をどのように処理しますか? ありがとう、コーリー

3
1つの実装を構築する多数。DI絶望?サービスロケーターを使用しますか?
インジェクションを受け入れるのではなく、依存関係を直接構築するクライアントが1001人いるとします。上司によると、1001のリファクタリングはオプションではありません。実際には、ソースへのアクセスさえ許可されていません。クラスファイルだけです。 私たちがやるべきことは、これらの1001クライアントが通過するシステムを「近代化」することです。好きなことをリファクタリングできます。依存関係はそのシステムの一部です。そして、それらの依存関係のいくつかは、新しい実装を行うために変更することになっています。 私たちがやりたいことは、この多数のクライアントを満たすために、依存関係の異なる実装を構成する機能を持っていることです。悲しいことに、クライアントはコンストラクターまたはセッターによるインジェクションを受け入れないため、DIはオプションのようには見えません。 オプション: 1)クライアントが使用するサービスの実装をリファクタリングして、クライアントが現在必要としていることを行うようにします。完了です。柔軟ではありません。複雑ではありません。 2)実装をリファクタリングして、ファクトリを通じて取得したさらに別の依存関係に作業を委任します。これで、ファクトリをリファクタリングすることで、すべてが使用する実装を制御できます。 3)実装をリファクタリングして、作業をサービスロケーターを介して取得したさらに別の依存関係に委任します。これhashmapで、少しのキャストが行われたオブジェクトへの文字列である可能性のあるサービスロケーターを構成することで、すべてが使用する実装を制御できます。 4)まだ考えていないこと。 目的: 設計が不十分な古いクライアントコードを無意味な複雑さを加えることなく未来にドラッグすることによって引き起こされる設計の損傷を最小限に抑えます。 クライアントは依存関係の実装を知っていないか制御するべきではありませんが、で構築することを主張しますnew。制御することはできませんnewが、構築しているクラスを制御します。 私の質問: 何を考慮しなかったのですか? Doc Brownからの質問 異なる実装間で構成する可能性が本当に必要ですか?何のために? 機敏。未知の多く。経営陣は変化の可能性を望んでいます。外の世界への依存を失うだけです。またテスト。 実行時の仕組みが必要ですか、それとも異なる実装を切り替えるためにコンパイル時の仕組みが必要ですか?どうして? コンパイルの時間の仕組みで十分です。テストを除く。 どの粒度で実装を切り替える必要がありますか?一斉に?モジュールごと(それぞれがクラスのグループを含む)?クラスごと? 1001のうち、一度に実行されるのは1つだけです。すべてのクライアントが一度に使用するものを変更しても問題はないでしょう。ただし、依存関係を個別に制御することはおそらく重要です。 誰がスイッチを制御する必要がありますか?あなた/あなたの開発者チームのみ?管理者ですか?各クライアントは自分で?または、クライアントのコードのメンテナンス開発者ですか?それでは、メカニックはどれほど簡単/堅牢/完全に機能する必要があるのでしょうか? テスト用の開発。外部ハードウェアの依存関係が変化するため、管理者。テストと構成が簡単である必要があります。 私たちの目標は、システムを迅速に作り直し、近代化できることを示すことです。 実装スイッチの実際の使用例 1つは、ハードウェアソリューションの準備が整うまで、一部のデータがソフトウェアによって提供されることです。

7
定型文の防御?
私にとって、定型的なコードは明らかに悪いです。しかし、ボイラープレートを減らすために抵抗を示す開発者に会いました。私は、私が長年にわたってそれに対して開発した嫌悪感を超えて、すぐに形成された、よく考えられた議論を持っていなかったことに気付きました。 定型文を少なくするという説得力のある議論を形成できるように、いくつかの反論は何ですか?言い換えれば、ボイラープレートを支持する議論(もしあれば)は何ですか? (私は一般的に定型語が意味すると思うものを意味しますが、良い例はJavaのゲッターとセッターです。)

10
既知のバグが解決されたときに、新しいバグが別の場所に表示される原因は何ですか?
議論の中で、私の同僚の一人は、バグを解決しようとしている間、彼の現在のプロジェクトにいくつかの困難があると言いました。「1つのバグを解決すると、他の何かが他の場所で機能しなくなります」と彼は言いました。 私はこれがどのように起こるのか考え始めましたが、それを理解することはできません。 疲れていたり眠すぎたりして、正しく作業できず、作業中のコードの一部を全体的に見ることができない場合、同様の問題が発生することがあります。ここで、問題は数日または数週間にあるようで、私の同僚の焦点とは関係ありません。 また、この問題は、非常に管理の行き届いていない非常に大きなプロジェクトで発生することも想像できます。チームメイトは、誰が何を行い、他の作業にどのような影響を与えるかがわからないのです。これもここでは当てはまりません。開発者が1人だけのかなり小さなプロジェクトです。 また、古い、メンテナンスが不十分で、ドキュメント化されていないコードベースの問題になる可能性があります。変更の結果を本当に想像できる唯一の開発者は、数年前に会社を去りました。ここでは、プロジェクトが始まったばかりで、開発者は誰のコードベースも使用していません。 それで、彼の仕事に集中し続ける一人の開発者によって書かれた新鮮な小さなコードベースで、そのような問題の原因は何でしょうか? 何が役立ちますか? 単体テスト(なし) 適切なアーキテクチャー(コードベースにはアーキテクチャーがまったくなく、予備的な考えなしに作成されたと確信しています)、リファクタリング全体が必要ですか? ペアプログラミング? 他に何か?

3
動的言語で書かれたコードをどのようにナビゲートしてリファクタリングしますか?
Python、Ruby、またはJavascriptを書くのに必要なボイラープレートが非常に少ないことが大好きです。シンプルな機能的構成が大好きです。簡潔でシンプルな構文が大好きです。 ただし、動的言語で大規模なソフトウェアを開発するとき、私が本当に苦手な点が3つあります。 コードのナビゲート 使用しているオブジェクトのインターフェイスを特定する 効率的なリファクタリング IDE(Eclipse + PyDev)と同様にシンプルなエディター(Vim)を試してきましたが、どちらの場合も、より多くのことをメモリにコミットする必要があります。インターフェース。これは、複数の依存関係を持つ大きなコードベースで作業する場合に特に当てはまります。 メソッド名の変更などのリファクタリングに関しては、単体テストの品質に大きく依存します。そして、アプリケーションの残りの部分を「カット」することによってユニットテストを分離しようとすると、スタブのインターフェイスがスタブしているオブジェクトに対して最新の状態に保たれるという保証はありません。 これらの問題には回避策があると確信しています。Python、Ruby、Javascriptでどのように効率的に作業しますか?

4
明らかな抽象化のないコード複製
コードの行を見たときに、ロジックにおけるその役割を忠実に説明するテーマの抽象化に適合できないコード重複のケースに遭遇したことはありますか?それに対処するために何をしましたか? これはコードの複製であるため、理想的には、たとえば独自の機能を作成するなどの屈折処理を行う必要があります。しかし、コードはそれを記述するための優れた抽象化を持たないため、結果は奇妙な関数になり、良い名前を見つけることすらできず、ロジックの役割はそれを見ただけでは明らかではありません。それは、私にとって、コードの明快さを傷つけます。明快さを保持し、そのままにしておくことはできますが、保守性が損なわれます。 このようなものに対処する最良の方法は何だと思いますか?

3
動的スコープを持つ言語でどのように安全にリファクタリングしますか?
動的スコープを持つ言語で動作しない幸運をお持ちの方のために、それがどのように機能するかについて少しおさらいさせてください。次のように動作する「RUBELLA」と呼ばれる擬似言語を想像してください。 function foo() { print(x); // not defined locally => uses whatever value `x` has in the calling context y = "tetanus"; } function bar() { x = "measles"; foo(); print(y); // not defined locally, but set by the call to `foo()` } bar(); // prints "measles" followed by "tetanus" …

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