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

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

16
上司から、小さな関数の作成をやめて、同じループですべてを実行するように頼まれました
Clean Codeという本を読みましたRobert C. Martinによる。この本では、小さな関数の作成、名前の慎重な選択など、コードをクリーンアップするための多くの方法を見てきました。しかし、今日、上司はこの本を読んだ後のコードの書き方が好きではありませんでした。 彼の議論は 小さな関数を書くと、コードが何をしているのかを見るために各小さな関数に移動しなければならないので苦痛です。 メインループが300行を超える場合でも、すべてをメインの大きなループに入れると、読みやすくなります。 コードを複製する必要がある場合にのみ、小さな関数を作成してください。 コメントの名前を使用して関数を記述しないでください。上記のコメントを使用して複雑なコード行(3〜4行)を入力してください。同様に、失敗したコードを直接変更できます これは私が読んだすべてのものに反しています。通常、どのようにコードを記述しますか?1つの大きなループ、小さな関数はありませんか? 私が使用する言語は主にJavascriptです。明確に名前が付けられた小さな関数をすべて削除し、すべてを大きなループに入れたので、今は本当に読みにくいです。しかし、上司はこの方法が好きです。 一例は次のとおりです。 // The way I would write it if (isApplicationInProduction(headers)) { phoneNumber = headers.resourceId; } else { phoneNumber = DEV_PHONE_NUMBER; } function isApplicationInProduction(headers) { return _.has(headers, 'resourceId'); } // The way he would write it // Take the right …

21
私のコードの大部分には大きな設計上の欠陥があります。終了するか、今すぐ修正しますか?[閉まっている]
私は高校生で、私の友人と一緒にC#プロジェクトに取り組んでいます。私のスキルレベルはほぼ同じです。これまでのところ、100件のコミットで約3,000行のコードと250行のテストコードを記述しました。学校のために、私は数ヶ月プロジェクトを延期し、最近私はそれを再び取り戻すことができました。 バックアップを取得するまでに、レンダラーに過剰なスレッドを含める、エミュレートされたCPU、GPU、ゲームカートリッジ間の相互作用における競合状態の防止が不十分であるなど、記述したコードの設計が不十分であることがわかりました、および単に冗長でわかりにくいコードも同様です。 問題は、プログラムの主要な機能すら完成していないため、真のリファクタリングができないことです。コードの設計に欠陥があることを完全に認識し続けることはできません。同時に、私はプロジェクトを放棄したくありません。かなりの量の進歩があり、作業が無駄になってはいけません。 私はいくつかの選択肢があるように感じます:貧弱なデザインを回避し、すべてが機能したらリファクタリングし、すべてを停止し、残りの機能が完了する前にすべてのもつれを解き、プロジェクトを開始することによって、単に機能を終了するそれがすべて私の心に再び新鮮であるように、または過度のサイズのためにプロジェクトを完全に放棄するように(本質的に「図面に戻る」)。 そのようなプロジェクトにおける他の人の経験に基づいて、自分を正しい軌道に乗せるための手段は何ですか?このサイトの回答から、一般的なコンセンサスは、書き換えは一般的に不要であるが、過剰なコストなしにコードを維持できない場合に利用可能なオプションであるということです。私は本当にこのプロジェクトを追求したいと思っていますが、現状では、私のコードは私が続けるのに十分に設計されておらず、落胆の感覚が私を継続からそらします。

9
直接オブジェクト構築の代わりにファクトリクラスを使用する必要があるのはなぜですか?
GitHubとCodePlexでいくつかのС#とJavaクラスライブラリプロジェクトの歴史を見てきました。オブジェクトの直接インスタンス化とは対照的に、ファクトリクラスに切り替える傾向が見られます。 なぜファクトリクラスを広範囲に使用する必要があるのですか?クラスのパブリックコンストラクターを呼び出すことで、昔ながらの方法でオブジェクトが作成される、非常に優れたライブラリがあります。最後のコミットで、著者は数千のクラスのすべてのパブリックコンストラクターCreateXXXをすぐに内部に変更し、クラスの内部コンストラクターを呼び出して新しいオブジェクトを返すだけの数千の静的メソッドを持つ1つの巨大なファクトリークラスを作成しました。外部プロジェクトAPIは壊れており、よくできています。 なぜこのような変更が役立つのでしょうか?このようにリファクタリングのポイントは何ですか?パブリッククラスコンストラクターの呼び出しを静的ファクトリメソッド呼び出しに置き換えることの利点は何ですか? いつパブリックコンストラクターを使用する必要があり、いつファクトリーを使用する必要がありますか?

13
「変更しない」とマークされたコードをリファクタリングする必要がありますか?
私はかなり大きなコードベースを扱っており、既存のコードをリファクタリングするために数ヶ月を与えられました。リファクタリングプロセスが必要なのは、すぐに製品に多くの新しい機能を追加する必要があり、現在のところ、他の機能を壊すことなく機能を追加することができなくなっているためです。要するに:私たちの多くが彼らのキャリアで見た、乱雑で巨大なバグのあるコード。 リファクタリング中に、時々、クラス、メソッド、または次のようなコメントのあるコード行に遭遇します モジュールAに何かをする時間を与えるためのタイムアウトセット。このようにタイミングが合わないと、壊れてしまいます。 または これを変更しないでください。私を信じて、あなたは物事を壊すでしょう。 または 私はsetTimeoutを使用することは良い習慣ではないことを知っていますが、この場合は使用しなければなりません 私の質問は、著者からのそのような警告に遭遇したときにコードをリファクタリングする必要がありますか(いいえ、著者と連絡を取ることができません)?


16
参照されていないコードを削除する必要がありますか?
私は中規模(10万行)のコードベースに取り組んでいます。それはすべて比較的新しいコード(1年未満)であり、ユニットテストのカバレッジが良好です。 どこでも使用されなくなったメソッドや、特定のメソッドのみをテストする単体テストでのみ参照されているメソッドに出くわします。 不要になったことが確実な場合、このコードを削除する必要がありますか? 削除する理由: 少ないコード、少ないバグ 他の人にとってはコードが少ないほど消化しやすい まだソース管理下にあります 維持する理由: 参照として使用できます いつか役に立つかもしれません クラスの機能を「概算」するために作成された可能性があります

12
インスタンス変数よりもローカル変数を好む理由は?
私が取り組んでいるコードベースでは、インスタンス変数を頻繁に使用して、さまざまな簡単なメソッド間でデータを共有しています。元の開発者は、これがアンクルボブ/ロバートマーティンによる「クリーンコード」の本で述べられているベストプラクティス、つまり「機能の最初のルールは小さくなければならない」に準拠していると断言します。「関数の理想的な引数の数はゼロ(niladic)です。(...)引数は難しいです。概念的な力を多く必要とします。」 例: public class SomeBusinessProcess { @Inject private Router router; @Inject private ServiceClient serviceClient; @Inject private CryptoService cryptoService; private byte[] encodedData; private EncryptionInfo encryptionInfo; private EncryptedObject payloadOfResponse; private URI destinationURI; public EncryptedResponse process(EncryptedRequest encryptedRequest) { checkNotNull(encryptedRequest); getEncodedData(encryptedRequest); getEncryptionInfo(); getDestinationURI(); passRequestToServiceClient(); return cryptoService.encryptResponse(payloadOfResponse); } private void getEncodedData(EncryptedRequest encryptedRequest) { encodedData = …
109 java  refactoring 

15
TDD Red-Green-Refactorおよびプライベートになるメソッドをテストするためのif / how
私が理解している限り、ほとんどの人は、プライベートメソッドを直接テストするのではなく、パブリックメソッドを呼び出してテストする必要があることに同意しているようです。私は彼らの要点を見ることができますが、「TDDの3つの法則」に従い、「赤-緑-リファクタリング」サイクルを使用しようとすると、いくつかの問題があります。例で説明するのが一番だと思います。 現在、ファイル(タブ区切りデータを含む)を読み取り、非数値データを含むすべての列をフィルターで除外できるプログラムが必要です。おそらくこれを行うためのシンプルなツールが既にいくつか用意されていると思いますが、TDDの練習をするのにすてきできれいなプロジェクトになりそうだと思ったため、最初から実装することにしました。 したがって、最初に、「赤い帽子をかぶる」、つまり、失敗するテストが必要です。私は、行内のすべての非数値フィールドを見つけるメソッドが必要だと考えました。だから、私は簡単なテストを書いて、もちろんすぐにコンパイルに失敗するので、関数自体の記述を開始し、2、3サイクル(赤/緑)前後に作業関数と完全なテストができました。 次に、ファイルを1行ずつ読み取り、最終的に削除する必要があるすべての列を収集するために各行で「findNonNumericFields」関数を呼び出す関数「gatherNonNumericColumns」を続行します。いくつかの赤と緑のサイクルがあり、作業機能と完全なテストが完了しました。 今、私はリファクタリングする必要があると考えています。私のメソッド「findNonNumericFields」は、「gatherNonNumericColumns」を実装するときに必要だと考えたために設計されたため、「findNonNumericFields」をプライベートにするのが合理的だと思われます。ただし、テストしていたメソッドにアクセスできなくなるため、最初のテストが中断されます。 だから、私はプライベートメソッドと、それをテストするテストスイートになります。多くの人がプライベートメソッドをテストすべきでないとアドバイスしているので、私はここで一角に自分を描いたように感じます。しかし、どこで正確に失敗しましたか? より高いレベルで始めて、最終的には私のパブリックメソッド(つまり、findAndFilterOutAllNonNumericalColumns)となるものをテストするテストを作成することもできましたが、それはTDDの全ポイントに少なくとも反すると感じます(少なくともボブおじさんによれば) :テストと本番コードの作成を絶えず切り替える必要があります。また、任意の時点で、すべてのテストが最後の1分以内に機能しました。パブリックメソッドのテストを書くことから始めた場合、プライベートメソッドのすべての詳細が機能するようになるまでに数分(または数時間、あるいは非常に複雑な場合は数日)があり、テストがパブリックをテストするためメソッドが渡されます。 じゃあ何をすればいいの?TDD(急速な赤緑リファクタリングサイクル)は、単にプライベートメソッドと互換性がありませんか?または、私の設計に欠陥がありますか?

20
最適化されたコードを読み取り可能なコードに置き換えても大丈夫ですか?
既存のコードを拡張/改善する必要がある状況に陥ることがあります。古いコードは非常にスリムですが、拡張するのも難しく、読むのに時間がかかります。 それを最新のコードに置き換えるのは良い考えですか? 少し前に私は無駄のないアプローチが好きでしたが、今では、より高い抽象化、より良いインターフェース、より読みやすく拡張可能なコードのために多くの最適化を犠牲にするほうが良いように思えます。 コンパイラも同様に良くなっているように見えるので、何も言わずstruct abc = {}にmemsetsに変わり、shared_ptrsは生のポインタをいじるのとほぼ同じコードを生成します。 それでも、スタックベースの配列や、いくつかのあいまいなロジックを持つ古いC関数が表示されることがありますが、通常はクリティカルパスにありません。 どちらかの方法でコードの一部に触れる必要がある場合、そのようなコードを変更することは良い考えですか?

11
テスト目的でコードを厳密に変更するのは悪い習慣ですか?
私はプログラマーの同僚と、テスト可能なものにするためだけに作業中のコードを変更するのが良いか悪いかについて議論しています(例えば、単体テストを介して)。 私の意見では、オブジェクト指向とソフトウェアエンジニアリングの優れた実践を維持することの範囲内で(「すべてを公開する」などではなく)OKです。 私の同僚の意見は、テスト目的でのみコードを修正するのは間違っているというものです。 単純な例として、一部のコンポーネント(C#で記述された)で使用される次のコードを考えてください。 public void DoSomethingOnAllTypes() { var types = Assembly.GetExecutingAssembly().GetTypes(); foreach (var currentType in types) { // do something with this type (e.g: read it's attributes, process, etc). } } 私は、このコードを修正して、実際の作業を行う別のメソッドを呼び出すことを提案しました。 public void DoSomething(Assembly asm) { // not relying on Assembly.GetExecutingAssembly() anymore... } このメソッドは、作業するAssemblyオブジェクトを取り込んで、テストを実行するために独自のAssemblyを渡すことを可能にします。私の同僚は、これが良い習慣だとは思いませんでした。 良い一般的な慣行とは何ですか?

10
Javaではクラスごとに何行が多すぎますか?[閉まっている]
あなたの経験では、Javaの1つのクラスには何行のコードが多すぎるかについての有用な経験則は何ですか? 明確にするために、行数は特定のクラスにあるべきものとそうでないものに使用する実際の標準にさえ近いものではないことを知っています。クラスは、適切なOOP哲学(カプセル化など)を念頭に置いて設計する必要があります。そうは言っても、経験則はリファクタリングの考慮事項の有用な出発点を提供することができます(つまり、「うーん、このクラスには> n行のコードがあります。ある時点でリファクタリングされます」)。 反対に、おそらく、OOP設計を順守し、長さにも関わらず読み取りと保守が可能な非常に大きなクラスの例に遭遇したことはありませんか? これは、関数ごとの行に関する、重複しない関連する質問です。

6
メソッド名のスペルミスを修正する
私のコードベースでよく使用する方法の1つは、つづりが間違っています(そしてそれは私よりも前のものです)。 これは単にスペルが間違っているだけでなく、もっと重要なことですが、最初にタイプするときに常に名前を間違えます(そして、「ああ、そうです、これにスペルを間違えるべきです...」) 元の方法を中心にいくつかの変更を行っています。機会を利用して、単におかしな方法の名前を変更する必要がありますか?

10
完全なリファクタリングの時間がないときに、レガシーコードのテストを書くことは理にかなっていますか?
私は通常、「Legacy Cod eで効果的に作業する」という本のアドバイスに従うようにしています。依存関係を壊し、コードの一部を@VisibleForTesting public staticメソッドと新しいクラスに移動して、コード(または少なくともその一部)をテスト可能にします。そして、新しい関数を変更または追加するときに何も壊さないことを確認するテストを作成します。 同僚は、私はこれをすべきではないと言っています。彼の推論: 元のコードはそもそも適切に動作しない可能性があります。また、開発者もテストを理解して変更する必要があるため、テストを作成すると将来の修正や変更が難しくなります。 何らかのロジック(〜12行、2〜3 if / elseブロックなど)を備えたGUIコードの場合、テストは簡単ではないので、テストを行う価値はありません。 同様の悪いパターンは、コードベースの他の部分にも存在する可能性があります(私はまだ見ていませんが、かなり新しいです)。1つの大きなリファクタリングですべてを簡単にクリーンアップできます。ロジックを抽出すると、この将来の可能性が損なわれる可能性があります。 完全なリファクタリングの時間がない場合、テスト可能な部分を抽出してテストを書くことを避けるべきですか?これに不利な点はありますか?

7
同僚が予告なしに不必要な改善を行った場合、どのようにコードに責任を負いますか?
私のチームメイトの1人はITショップのすべての取引のジャックであり、私は彼の洞察を尊重しています。 ただし、彼は時々頭を使わずに私のコードをレビューします(彼はチームリーダーの2番目の指揮官なので、それは予想されています)。そのため、時々、彼は最終目標を完了する前に私の変更をレビューし、すぐに変更を加えます。 また、3か月以上前のコードの一部に不要な改善を加えた場合もあります。 これにはいくつかの理由があります。 間違いを修正する機会が常に与えられるとは限らない 彼は、彼が混乱しているときに私が何を達成しようとしていたかを尋ねる時間をとっていないので、テストや変更に影響を与える可能性があります 彼のコードが読めるとは限らない 期限は問題ではなく、彼の現在のワークロードは、コードの変更を確認する以外に私のプロジェクトでの作業を必要としません。 とにかく、私は過去に彼が私のコードの所有権を取得できるように変更したい何かを私の仕事で見た場合、私に投稿してくださいと言いました(多分私は「欠点」と言うべきでした)、彼は応答しませんでした。 彼に私に彼の変化を説明するように頼むとき、私は攻撃的になるかもしれないと恐れています。 彼は自分を守る静かな人ですが、彼の行動は続きます。私たちはチームであるため、私は彼にコードの変更を禁止したくありません(できませんでしたが)。 説明を追加: 1つの開発ブランチを共有しています。重要な作業を失うリスクがあるため、すべての変更が1つのタスクを完了するまで待機しません。したがって、変更を確実にビルドし、何も壊さないようにします。 私の懸念は、チームメイトが彼の変更の背後にある理由や目的を説明していないことです。私は彼が私の祝福を必要とするべきではないと思うが、私たちがアプローチに同意しない場合、私たちが長所と短所を議論し、両方が何が起こっているかを理解したら決定を下すことが最善だと思った。 これはチームリーダーとはまだ話し合っていません。必要でない限り、経営陣が関与することなく個人的な意見の不一致を解決したいからです。私の懸念は私たちの仕事に対する脅威というよりも個人的な問題のように思われたので、チームリーダーを煩わせないことにしました。私は、コードレビュープロセスのアイデアに取り組んでいます。これは、私のペットの気持ちをすべて気にすることなく、より組織的なコードレビューのメリットを促進するためです。

2
目的がわからないコードのテストを書く
私は最近、ブラックボックスのリファクタリングを完了しました。テストする方法がわからないので、チェックインできません。 高レベルでは、クラスBから値を取得する初期化を含むクラスがあります。クラスBが「空」の場合、適切なデフォルトが生成されます。クラスBを同じデフォルトに初期化するメソッドにこの部分を抽出しました。 どちらのクラスの目的/コンテキスト、またはそれらがどのように使用されるかについてはまだ解明していません。そのため、空のクラスBからオブジェクトを初期化することはできませんし、正しい値を持っている/正しいことを行っていることを確認してください。 私の最善のアイデアは、元のコードを実行し、初期化されたメンバーに応じてパブリックメソッドの結果をハードコードし、それに対して新しいコードをテストすることです。この考えに漠然と不快感を覚える理由を明確に述べることはできません。 ここにはより良い攻撃がありますか?

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