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

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

17
リファクタリングをチームの優先事項にするにはどうすればよいですか?
私が毎日使用しているコードベースには、自動テスト、一貫性のない命名、「なぜこれが必要なのか」、「これが必要かどうかわからない」、「このメソッドに正しい名前が付けられていない」などの大量のコメントがなく、コードが散らかっていますソース管理を使用しているにもかかわらず、「変更ログ」。私たちのコードベースはリファクタリングを使用できると言えば十分です。 バグを修正したり、新しい機能を追加したりするタスクは常にあるため、コードをリファクタリングしてよりモジュール化するための時間は確保されておらず、優先度は高くないと思われます。 タスクリストに追加されるようなリファクタリングの価値をどのように実証できますか?許可ではなく許しを求めて、リファクタリングするだけの価値はありますか?

9
リファクタリングする前に単体テストを書く方法は?
「リファクタリング時にユニットテストをどのように機能させ続けるのですか?」などの同様の行に沿って質問に対するいくつかの回答を読みました。私の場合、私たちが持っているいくつかの標準をレビューし、それに合わせるプロジェクトを与えられたという点で、シナリオはわずかに異なります。現在、プロジェクトのテストはまったくありません! サービスレイヤーにDAOタイプのコードを混在させないなど、改善できたと思われる多くのことを特定しました。 リファクタリングする前に、既存のコードのテストを書くことは良い考えのように思えました。私に見える問題は、リファクタリングを行うと、特定のロジックが実行される場所を変更しているため、これらのテストが壊れ、テストが以前の構造を念頭に置いて書かれていることです(依存関係のモックなど) 私の場合、手続きを進める最善の方法は何でしょうか?私はリファクタリングされたコードの周りにテストを書きたいと思っていますが、望みの振る舞いを変える可能性のあるものを間違ってリファクタリングするリスクがあることを知っています。 これがリファクタリングであろうとリデザインであろうと、これらの用語の修正を理解できてうれしいです。現在、次のリファクタリングの定義に取り組んでいます。「リファクタリングでは、定義により、ソフトウェアの動作は変更されません方法を変えることができます。」だから、私はソフトウェアが何をするかを変えていません。 同様に、再設計と考えられるメソッドのシグネチャを変更する場合の議論を見ることができます。 簡単な例を示します MyDocumentService.java (現在) public class MyDocumentService { ... public List<Document> findAllDocuments() { DataResultSet rs = documentDAO.findAllDocuments(); List<Document> documents = new ArrayList<>(); for(DataObject do: rs.getRows()) { //get row data create new document add it to //documents list } return documents; } } MyDocumentService.java (何でもリファクタリング/再設計) public …

12
ボーイスカウトルールと日和見的リファクタリングとコードレビューの調整
私はボーイスカウトルールを大いに信じています。 オリジナルの作者が誰であっても、モジュールを改善するためにどんなに小さな努力をしたとしても、結果はどうなるでしょうか?すべてがその単純なルールに従っており、ソフトウェアシステムの容赦ない劣化の終わりが見えますが、代わりに、システムが進化するにつれて徐々に改善されていきます。自分の小さな部分を気遣うだけの個人よりも。 私はまた、日和見的リファクタリングの関連するアイデアを強く信じています。 いくつかのスケジュールされたリファクタリングの努力のための場所がありますが、私は、いつでもどこでもコードをクリーンアップする必要があるとき、誰によってでも行われる日和見的な活動としてリファクタリングを奨励することを好みます。これが意味することは、誰かがそれほど明確でないコードを見たときはいつでも、すぐにそれを修正する機会をとるべきだということです-少なくとも数分以内に 特に、リファクタリングの記事からの次の抜粋に注意してください。 私は日和見的リファクタリングの摩擦を引き起こす開発慣行には警戒しています...私の感覚では、ほとんどのチームは十分なリファクタリングを行っていないので、人々がそれを行わないよう注意を払うことが重要です。これを洗い流すのを助けるために、小さなリファクタリングを行うことを思いとどまるときはいつでも気をつけてください。確かに1、2分しかかかりません。そのような障壁は、会話を促す匂いです。そのため、落胆のメモを取り、チームに報告してください。少なくとも、次の回顧展で議論する必要があります。 私が働いているところでは、大きな摩擦を引き起こす開発プラクティスが1つあります。それは、コードレビュー(CR)です。「割り当て」の範囲にないものを変更するたびに、レビュー担当者に非難され、変更をレビューしにくくします。これは、リファクタリングが関係する場合に特に当てはまります。「行ごと」の比較比較が困難になるためです。このアプローチはここでの標準です。つまり、日和見的リファクタリングはめったに行われず、「計画された」リファクタリング(通常は少なすぎる、遅すぎる)が行われます。 私は、メリットはそれだけの価値があり、3人のレビュアーが少し一生懸命に働くと主張しています(変更された行の狭い範囲を見るのではなく、実際に前後のコードを理解するために-レビュー自体はそれだけで良いでしょう) )コードを読んで保守する次の100人の開発者が恩恵を受けるように。この論点をレビューアーに提示すると、同じCRにない限り、リファクタリングに問題がないと彼らは言います。しかし、私はこれが神話だと主張しています: (1)ほとんどの場合、課題の最中に何をどのようにリファクタリングしたいかを認識するだけです。マーティン・ファウラーが言うように: 機能を追加すると、追加するコードに既存のコードとの重複が含まれていることに気付くため、既存のコードをリファクタリングしてクリーンアップする必要があります...何か機能するかもしれませんが、既存のクラスとの相互作用が変更された場合に優れています。自分が完了したと考える前に、その機会にそれを行ってください。 (2)実行するはずのない「リファクタリング」CRをリリースすることを好む人はいません。CRには一定のオーバーヘッドがあり、マネージャーはリファクタリングに「時間を浪費する」ことを望んでいません。行うべき変更にバンドルされている場合、この問題は最小限に抑えられます。 問題はResharperによって悪化します。変更に追加する各ファイル(および最終的にどのファイルが変更されるか正確に知ることはできません)には、通常、エラーと提案が散らばっています。修正。 最終的な結果は、ひどいコードが表示されることであり、そのまま残します。皮肉なことに、このようなコードを修正しても私の地位が向上するだけでなく、実際にはそれらを下げて、仕事をする代わりに誰も気にしないものを修正する時間を無駄にする「焦点のない」男として描く 私は本当に悪いコードを軽deし、それを見て我慢できず、私のメソッドからそれを呼び出すことができないので、私はそれについて悪いと感じています! この状況をどのように解決できるかについての考えはありますか?

2
「機能がうらやましい」コードとは何ですか。なぜコードのにおいと見なされるのですか?
SOに関するこの質問は、OPが機能en望のコードだと考えているものを修正することについて語っています。この気の利いたフレーズが引用されているのを私が見た別の例は、ここでprogrammers.SEで最近与えられた答えです。私はその答えにコメントを入れて情報を求めましたが、Q&Aを読んでプログラマがfeature-envyという用語の意味を理解することは一般的な助けになると思いました。適切と思われる場合は、追加のタグを自由に編集してください。

11
カスケードリファクタリングを回避するにはどうすればよいですか?
プロジェクトがあります。このプロジェクトでは、機能を追加するためにリファクタリングしたいと考え、機能を追加するためにプロジェクトをリファクタリングしました。 問題は、作業を終えたときに、それに対応するためにインターフェイスを少し変更する必要があることが判明したことです。だから私は変更を加えました。そして、新しいクラスの観点から、現在のインターフェイスでは消費クラスを実装できないため、新しいインターフェイスも必要です。今では3か月後に、無数の事実上無関係な問題を修正する必要があり、1年前にロードマップされた問題、または問題がコンパイルされる前に修正できないと単純にリストされている問題の解決を検討しています再び。 この種のカスケードリファクタリングを今後回避するにはどうすればよいですか?これは、以前のクラスが互いに緊密に依存しすぎているという単なる症状ですか? 簡単な編集:この場合、リファクタリングは機能でした。これは、リファクタリングにより特定のコードの拡張性が向上し、一部の結合が減少したためです。これは、外部の開発者がより多くのことができることを意味し、それが私が提供したかった機能でした。したがって、元のリファクタリング自体は機能的な変更ではないはずです。 5日前に約束したより大きな編集: このリファクタリングを開始する前に、インターフェイスのあるシステムがありましたが、実装では、dynamic_cast出荷したすべての可能な実装を単純に確認しました。これは明らかに、インターフェイスから継承することはできなかったことを意味し、第2に、このインターフェイスを実装するための実装アクセス権を持たない人は不可能であることを意味しました。だから私はこの問題を修正し、誰でもそれを実装できるようにインターフェースを公開し、誰でもそれを実装できるようにし、インターフェースの実装が必要な契約全体であると判断しました。 私がこれをしたすべての場所を見つけて火で殺そうとしていたとき、特定の問題であることが判明した場所を1つ見つけました。それは、さまざまな派生クラスのすべての実装の詳細と、すでに実装されているが他のどこかより優れた複製機能に依存していました。代わりにパブリックインターフェイスの観点から実装し、その機能の既存の実装を再利用することもできます。正しく機能するには特定のコンテキストが必要であることを発見しました。おおまかに言って、呼び出し元の以前の実装はちょっと似ていました for(auto&& a : as) { f(a); } ただし、このコンテキストを取得するには、次のようなものに変更する必要がありました std::vector<Context> contexts; for(auto&& a : as) contexts.push_back(g(a)); do_thing_now_we_have_contexts(); for(auto&& con : contexts) f(con); これは、以前はの一部であったすべての操作についてf、一部はgコンテキストなしで動作する新しい関数の一部にする必要があり、一部は現在の遅延の一部で行う必要があることを意味しますf。しかし、すべてのメソッドf呼び出しがこのコンテキストを必要とするわけでも、必要とするわけでもありません。一部のメソッドは、別個の手段で取得する別個のコンテキストを必要とします。そのため、最終的にf呼び出しを行うすべて(大まかに言えば、ほぼすべて)について、必要なコンテキスト(ある場合)、取得元、および古いものからf新しいものへの分割方法を決定する必要がfありましたg。 そして、それが私が今いるところに行き着いた方法です。とにかく他の理由でこのリファクタリングが必要だったからです。

14
関数内のパラメーターの順序に関するベストプラクティスは何ですか?
時々(まれに)、適切な量のパラメーターをとる関数を作成することが最適なルートであると思われます。しかし、そうすると、パラメーターの順序をランダムに選択することが多いように感じます。私は通常、最も重要なパラメーターを最初に使用して、「重要度の順に」進みます。 これを行うためのより良い方法はありますか?明確性を高めるパラメーターを並べる「ベストプラクティス」の方法はありますか?

21
リファクタリングを非技術者にどのように説明しますか?
リファクタリング(および技術的負債)を非技術者(通常はPHBまたは顧客)にどのように説明しますか?(「なんと、目に見える違いなくあなたの仕事に1か月かかるでしょうか!」) 更新これまでのすべての回答に感謝します。このリストは、適切な人を指すことができるいくつかの有用な類推を提供すると思います(PHBへの参照を編集するのは賢明かもしれません!)

5
エンドユーザーの命名法が変更された場合、コードとデータの名前をどこまで変更する必要がありますか?
かなり前に、ワークフローキューに追加された画像をユーザーが「受け入れる」機能を追加しました。結局、間違った用語を使用し、ユーザーは実際に画像を「承認」しました。 インターフェースのAcceptをApproveに変更するのは簡単です。1つの単語を置き換えるだけです。ただし、CSSクラス名からデータベース値まで、すべてのレイヤーを「accept」という単語でプログラミングしました。 ボタンを緑色にするCSSクラス: ".accepted"; DOMノードのクラス属性を検証およびバインドするモデルメソッド: "isAccepted"; JavaScriptステータス属性:「未確認」、「承認済み」、「公開済み」の配列。 Mysqlステータス列:「未確認」、「承認済み」、「公開済み」のENUM。 テスト名; 承認する承認のほとんどの出現を置き換えることは簡単です(特にテストがある場合)。特に、展開と同期する必要があるため、データを移行するのが少し難しくなります。 この特定のケースは単純ですが、私のキャリアの中で、同様の、さらに複雑なケースに直面しました。ファイルの名前も変更され、数十台のサーバーで展開が行われる場合、またはプロキシキャッシングの場合、memcachedとmysqlが関係します。 インターフェース以外のすべてのレイヤーに「受け入れられた」ままにしておくのは悪い考えです。チームに参加する新しいプログラマーは、この決定に至った歴史的な理由を学ばない可能性があるためです。 「管理上の次のステータス会議のためにキューに入れられました」に名前が変更されました、それは確かに意味をなさないでしょう。そして、あちこち妥協しても、ユーザーインターフェイスの概念はシステムの内部に影響を与えないことを何度か繰り返しますが、出力の半分が内部に接続されていないシステムで作業したくはありません。 だから、必要なときに常にすべての名前を変更していますか?これがあなたに起こり、トレードオフは価値がないと判断した場合、それはあなたを噛むために戻ってきましたか?この問題を回避するには、コードコメントまたは開発者向けドキュメントで十分ですか?

15
1スプリントよりも時間がかかるリファクタリングを処理するにはどうすればよいですか?
私は50万行を超えるコードであるコードベースを使用しています。リファクタリングが非常に必要です。通常の2週間のスプリントよりも時間がかかるリファクタリング作業が特定されています。このサイトの他の回答で提案したように、これらを小さなタスクに分割することはできません。製品は反復の最後に動作する必要があり、部分的なリファクタリングは、アイテム間の依存関係が恐ろしいため、システムを使用できない状態のままにします。それでは、このハードルにアプローチする最良の方法は何でしょうか?繰り返しますが、それを小さな断片に分割することはオプションではなく、すでに行われています。 更新:人々はなぜこれが2週間のスプリントに収まらないのかの説明が必要なようです。コードを書くだけでなく、スプリントに関与します。私たちには、テストなしのコードはないというポリシーがあります。そのポリシーは常に存在するとは限らず、コードベースの大部分にはそれらがありません。また、統合テストの一部はまだ手動テストです。問題は、リファクタリング自体が非常に大きいということではありません。小さな変更がシステムの多くの部分に影響を与えるという事実があり、それらの部分が依然として正しく動作することを保証する必要があります。 毎月のホットフィックスがあるため、スプリントを延期または延長することはできません。したがって、スプリントを超えて拡張されるこの変更は、修正プログラムに追加される他の作業を停止できません。 リファクタリングと再設計:開発プロセスが2週間のサイクルでこのリファクタリングを処理するのに十分な効率がないため、再設計に名前を変更する必要はありません。将来的には、プロセスが改善されれば、2週間のサイクル内でまったく同じタスクを達成できると信じています。ここで問題になっているコードは、長い間変更する必要がなく、非常に安定しています。現在、会社の方向性が変化に適応しやすくなっているため、コードベースのこの部分が他の部分と同じように適応できるようにしたいと考えています。リファクタリングが必要です。ここでの回答に基づいて、通常のスプリントの時間枠でこのリファクタリングを機能させるために必要な足場が不足していることが明らかになりつつあります。 回答: これらの問題領域と欠落しているテストを特定する方法についてさらに学習できるように、Corbin Marchが初めて提案したブランチとマージのアプローチを実行します。前進するためには、Buhbが提案したテストに欠けている領域を特定するアプローチを採用し、それらを最初に実装してからリファクタリングを行う必要があります。ここで多くの人がリファクタリングの場合は常にそうすべきだと言っているように、通常の2週間のスプリントサイクルを維持することができます。

10
肥大化したGUIコードの記述を避けるにはどうすればよいでしょうか?
GUIコードを使用すると、コードが他の種類のコードよりも速く膨張する傾向があります。また、リファクタリングが難しいようです。一方、他の種類のコードではかなり簡単にリファクタリングできます-より大きなクラスをより小さな機能に分解できることがわかります-ほとんどのGUIフレームワークでは、多くの場合、ウィジェット/コントロール/クラスを必要とするフレームワークに縛られていますウィジェット/コントロール/その他にもっと多くのものを直接実装します。これは、(a)いくつかのベースウィジェット/コントロール/ものから継承するか、(b)保護されたメソッドにアクセスする必要があるためです。 また、通常、たとえば、フレームワークからの信号/イベント/何でもを介して多種多様な入力に応答して、ユーザーと対話するすべてのモードを実装する必要があります。1つのGUIウィジェット/コントロールで、次のようなさまざまな入出力を処理する必要がある場合があります。 右クリック/コンテキストメニュー コンテキストメニューからの選択に反応する GUIをペイントする特別な方法 キーボード入力に反応する ボタン、チェックボックス、 などなど ...その間、ビジネスロジックを表すGUIの下でクラスを管理します。 シンプルでわかりやすいGUIでは、ビジネスロジックを分離してMVCを使用する場合でも、コードを非常に迅速に成長させることができます。GUIコードは変更の大きな魅力です。 GUIコードを健全な方法で管理し、壊れたウィンドウにならないようにする方法はありますか?それとも、ランダムなイベントハンドラー/オーバーライドされたメソッドの塊が、GUIコードに対してできる最善の方法なのでしょうか。
48 refactoring  gui 

7
リファクタリングの潜在的な価値を測定する方法
技術的な負債を抱える古い大規模なプロジェクトでは、リファクタリングコードの利点をどのように確実に推定または測定できますか? たとえば、古い言語で記述されたソフトウェアスタックソリューション内のコンポーネントと、新しい言語で記述された後のコンポーネントがあるとします。このソリューションには、開発チームによって常に新しい機能とバグ修正が追加されています。 開発者は、既存の古い言語コンポーネントを新しいバージョンに置き換えることは「良いこと」だと提案します。ただし、この作業によって追加の機能は追加されず、x開発日数かかります。 営業担当者は、「すばらしい新機能」を追加することを提案しています。会社は数式を使用して提案の価値を測定します。すなわち。x dev-daysの作業コストで、t年間でFポンドを獲得します。 どうすれば会社はリファクタリングの提案に意味のあるコストをかけることができますか?そして、どのような状況下でそれが会社にとって最も収益性の高いオプションになる可能性がありますか?

8
コードのメンテナンス:一貫性を保つために新しいコードを拡張する際に悪いパターンを維持するかどうか?
プロジェクトの既存のモジュールを拡張する必要があります。私はそれが行われた方法が好きではありません(コピー/貼り付けられたコードのような、アンチパターンがたくさんあります)。多くの理由で完全なリファクタリングを実行したくありません。 したほうがいい: 次のメンテナーとの混乱を避け、コードベースとの一貫性を保つために、間違っていると感じたとしても、既存の規則を使用して新しいメソッドを作成しますか? または コードに別のパターンを導入している場合でも、私が気分が良いものを使用してみてください? 最初の回答後に編集された精度: 既存のコードは混乱ではありません。簡単に理解できます。しかし、良いデザインで回避できる多くの定型コードを導入しています(その結果、コードを追跡するのが難しくなるかもしれません)。私の現在のケースでは、古き良きJDBC(インボードのスプリングテンプレート)DAOモジュールですが、すでにこのジレンマに遭遇しており、他の開発者フィードバックを探しています。 時間がないので、リファクタリングしたくありません。そして、時間が経っても、完全に機能するモジュール全体にリファクタリングが必要であることを正当化するのは困難です。リファクタリングのコストは、そのメリットよりも重いでしょう。覚えておいてください:コードは乱雑でも複雑でもありません。そこにいくつかのメソッドを抽出して、ここで抽象クラスを紹介することはできません。それは設計上の欠陥です(極端な「愚かなシンプルを保つ」の結果だと思います) したがって、質問はそのように尋ねることもできます: 開発者として、あなたは簡単な愚かな退屈なコードを維持することを好みますか、またはあなたの場所で愚かな退屈なコードを行うヘルパーを持っていますか? 最後の可能性の欠点は、いくつかのことを学ばなければならず、完全なリファクタリングが完了するまで、簡単な愚かな退屈なコードを維持しなければならないことです)

10
コードをクリーンアップするために定期的な時間をスケジュールすることは良い考えですか?[閉まっている]
私は小さな開発者チームを管理しています。コードをクリーンアップするために、1〜2日を費やすことにします。 コードベースをクリーンアップするために、2か月ごとに1週間などの定期的な時間をスケジュールすることをお勧めしますか?

6
大きなファイルのリファクタリングを処理する最良の方法は何ですか?
現在、残念ながらソフトウェア品質ガイドラインが常に守られているわけではないファイルを含む、より大きなプロジェクトに取り組んでいます。これには、明らかに複数の異なる機能を含む大きなファイル(2000〜4000行を読む)が含まれます。 次に、これらの大きなファイルを複数の小さなファイルにリファクタリングします。問題は、彼らがとても大きいので、異なるブランチの複数の人々(私を含む)がこれらのファイルで作業していることです。ですから、これらのリファクタリングを他の人々の変更とマージすることが難しくなるので、私は実際に開発とリファクタリングから分岐することはできません。 もちろん、全員がマージしてファイルを開発し、ファイルを「フリーズ」し(つまり、誰もファイルを編集できないようにする)、リファクタリングしてから「フリーズ解除」する必要があります。しかし、リファクタリングが完了するまでこれらのファイルに対する作業を基本的にすべて停止する必要があるため、これもあまり良くありません。 だから、リファクタリングする方法がありますか、他の誰かに作業を停止することを要求しないでください(長い間)、または開発のために機能ブランチをマージして戻しますか?

6
SQLのリファクタリングが容易ではないのはなぜですか?[閉まっている]
新しい開発者が長い関数を書くことは誰もが知っています。進歩するにつれて、コードを小さな断片に分割するのが上手になり、経験がそうすることの価値を教えてくれます。 SQLを入力します。はい、SQLのコードについての考え方は、手順についてのコードについての考え方とは異なりますが、この原則は同じように思えます。 次の形式のクエリがあるとします。 select * from subQuery1 inner join subQuerry2 left join subquerry3 left join join subQuery4 いくつかのIDや日付などを使用する これらのサブクエリはそれ自体が複雑であり、独自のサブクエリを含む場合があります。他のプログラミングコンテキストでは、複雑なサブクエリ1〜4のロジックは、それらすべてを結合する親クエリに一致するとは考えられません。私が手続き型コードを書いている場合にそれらが関数であるように、それらのサブクエリはビューとして定義されるべきであるように非常に簡単です。 では、なぜ一般的な慣行ではないのでしょうか?なぜこれらの長いモノリシックSQLクエリを頻繁に書くのですか?なぜ手続き型プログラミングが広範な関数の使用を奨励するように、SQLが広範なビューの使用を奨励しないのか。(多くのエンタープライズ環境では、ビューの作成は簡単にできるものではありません。要求と承認が必要です。他のタイプのプログラマーが関数を作成するたびに要求を送信しなければならないと想像してください!) 私は3つの可能な答えを考えました: これはすでに一般的であり、私は経験の浅い人々と仕事をしています 経験豊富なプログラマーは、手続き型コードを使用してハードデータ処理の問題を解決することを好むため、複雑なSQLを作成しません 他の何か

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