1

私は巨大なクラスを持っていますA。これをリファクタリングして、その動作の一部を含む部分クラスを抽出します。今、私は 10 個の部分クラスに 1 ステップでリファクタリングしたくありませんAが、最初の動作を にリファクタリングしB、次にこのクラスに触れたときに継続的なリファクタリング方法で、別の動作を にリファクタリングしたいと考えていCます。

次に、Aこれは一種のmain意志受け入れDI方法として機能Bし、Cそれらをヘルパーとして使用します。

私の問題はこれです:

これは部分的なリファクタリング (連続...)Bであり、リファクタリングが不可能なCロジックに依存しているため、ロジックに依存していない場合は、10 または 20 のクラスにすぐに分割する必要があります。AABCBCAA

私に残っているのはこれです:

  1. Bそして、(醜い)方法でC受け入れますが、醜いですが、これにより継続的なリファクタリングを行うことができます。さらに悪いことに、準備ができていませんが、ヘルパーと.ADIABC
  2. 完全なリファクタリングを行います - できません! 複雑すぎてリスクが高すぎるので、一歩一歩進んでいくのが好きなので、それも受け入れられません! リファクタリングに小さなステップが必要で、リファクタリングを段階的に構築します。コードに触れるたびに、少しのクリーンアップとリファクタリング (レガシー コード) を行いますが、一度にすべてをリファクタリングすることはできません。
  3. DIセッターも受け入れられません。私は依存関係を好みctorます。

これに関するアイデアはありますか?これのパターンはありますか?

4

4 に答える 4

2

通常、これらはリファクタリングに使用した手順/ルールです。これらの手順を実行しても、通常は問題はありません。例は C# です。

  1. 静的関数の削除 (オプション)

    静的関数を削除したい場合は、通常、それをクラスとしてラップし、デフォルトのフィールド注入を行います (in C#is プロパティ)。通常、これはステートレス関数に対して行われていることに注意してください。

    public static class StaticExample{
        public static void DoSomething(int a){ /*code here*/ }
    }
    public class WrapperExample{
        public void DoSomething(int a){ return StaticExample.DoSomething(a); }
    }
    public class Consumer{
        public WrapperExample wrapperExample = new WrapperExample();
        public void ConsumeBefore(int a){ StaticExample.DoSomething(a); }
        public void ConsumeAfter(int a){ wrapperExample.DoSomething(a); }
    }
    

    これにより、現在のロジックへの影響はゼロになり、より多くのリファクタリング (依存関係の挿入、静的を使用しないように Wrapper を変更するなど) のための優れたベースラインが提供されます。

  2. 最初にエンドポイントをリファクタリングする

    通常、関数はいくつかのステップを実行します。いくつかの例は次のとおりです。

    • カートのチェックアウト: カート項目の取得、カートの検証、支払いの検証、保管数量の減算、カートを完了としてマーク、[請求書の印刷] <-- これがエンドポイントです

    • answer stackoverflow question: 回答の取得、回答の検証、回答の挿入/公開済みとしてマーク、[通知の送信] <-- これがエンドポイントです

    これは通常、次の理由により簡単に実行できます。

    1. 通常、エンドポイントの実行中に必要な外部リソース (パラメーター / 変数 / データ) はありません。
    2. 通常、多くのデータ操作は必要ありません。

    3. 通常、データベースやプリンターなどの外部依存関係との相互作用があり、抽出する価値があります。

    ポイント1は通常、リファクタリングされたクラスで循環依存を解決します。

  3. ステートレスにします。ステートフルな場合は、パラメーターにリファクタリングします

    あなたのクラスの1つがこれを持っているとしましょう:

    public class Foo(
        public string Bar = "";
        public void DoSomething(){
            // the code you want to refactor using Bar
        }
    )
    

    なる

    public class Foo(
        public string Bar = "";
        public RefactoredClass refactoredClass = new RefactoredClass();
        public void DoSomething(){
            refactoredClass.DoSomething(Bar);
        }
    )
    
  4. いくつかの類似したパラメーターが DTO になる

    このリファクタリングは、パラメーターが多すぎることを単純化することを目的としています。通常、これは、パラメーターのセットが互いに何らかの関係を持っているかどうかを意味します。例(実際のシナリオではないかもしれません):

    string cartId, string productId, int quantity --> CartItem
    string cartId, string productId, int quantity, string userName, string invoiceNumber --> this is not right
    

    最初の例は、パラメーターがまだ同じコンテキストにあるため、DTO にリファクタリングできます ( CartItem)。2 番目の例では、 and のコンテキストはuserNameandinvoiceNumberに関連していませproductIdquantity

    SRP関数が2つの異なるものを処理するように見えるため、違反につながる可能性があります。ただし、 の配列を持つ にuserNameinvoiceNumberを埋め込むと、請求書を印刷するための 1 つのコンテキストになります。CartHeaderCartItems

これは私の 2 セントです。ソースや参考文献はありません。

于 2013-07-31T08:11:30.030 に答える
1

この正確な問題について語る公式のリファクタリング抽出クラスパターンで「公式の」答えを見つけました:

http://sourcemaking.com/refactoring/extract-class

力学

06 クラスの役割分担を決める。分割された責任を表す新しいクラスを作成します。古いクラスの責任がその名前と一致しなくなった場合は、古いクラスの名前を変更します。古いクラスから新しいクラスへのリンクを作成します。 双方向リンクが必要な場合があります。ただし、必要になるまでバックリンクを作成しないでください。

そのため、この双方向リンクを作成する以外に方法がない場合があります。

于 2013-07-30T13:11:31.360 に答える
-1

Mediator パターンを試してください。A と部分クラス間のすべての相互作用は、メディエーター クラスにカプセル化する必要があります。

于 2013-07-30T09:42:35.360 に答える