1

たくさんのメソッドを持つクラスがありました:

public class MyClass {
    public bool checkConditions() {
        return checkCondition1() &&
               checkCondition2() &&
               checkCondition3();
    }

...conditions methods

    public void DoProcess() {
        FirstPartOfProcess();
        SecondPartOfProcess();
        ThirdPartOfProcess();
    }

...process methods
}

私は2つの「重要な」作業領域を特定し、それらのメソッドを独自のクラスに抽出することにしました。

public class MyClass {
    private readonly MyClassConditions _conditions = new ...;
    private readonly MyClassProcessExecution = new ...;

    public bool checkConditions() {
        return _conditions.checkConditions();
    }

    public void DoProcess() {
        _process.DoProcess();
    }
}

Javaでは、MyClassConditionsとをMyClassProcessExecutionとして定義しますpackage protectedが、C#ではそれを行うことはできません。


C#でこれをどのように実行しますか?

両方のクラスをMyClassの内部クラスとして設定しますか?

私には2つのオプションがあります:私はそれらを内部で定義し、すべてを同じファイルに入れMyClassて混乱させて醜いように見えるか、またはMyClassとして定義することができます。partial classMyClassMyClassConditionsMyClassProcessExecution

それらを内部として定義しますか?

これらのクラスがプログラム/アセンブリの残りの部分にまったく値を追加しないので、内部修飾子の多くはあまり好きではありません。可能であれば、それらを非表示にします。プログラムの他の部分で役立つ/再利用できるわけではありません。

それらを公開しておきますか?

理由はわかりませんが、ここでこのオプションを許可しました。

他の?

それに名前を付けます!

ありがとう

4

5 に答える 5

2

現在のアセンブリの外部で使用されない「ヘルパー」タイプのクラスのInternal場合、メソッドが複数のクラスで使用される場合に使用する方法です。

単一のクラスでのみ使用されるメソッドの場合は、クラスに対してプライベートにするか、実際には他の場所で使用されていないクラスの場合は内部クラスを使用します。コードがクラスの(非静的)メンバーに依存していない場合は、コードを静的メソッドに分解することもできます。

于 2010-05-13T19:00:45.137 に答える
2

最善の策は、おそらく部分的なクラスを使用し、コードの3つの塊を別々のファイルに入れて同じクラスに追加することです。次に、条件コードとプロセスコードをプライベートにして、クラス自体だけがアクセスできるようにします。

于 2010-05-13T19:05:03.813 に答える
1

MyClassを部分クラスとして定義できます。1つのファイルはMyClass用、もう1つはMyClassConditions用、もう1つはMyClassProcessExecution用です。

たぶんそれは私のC++のバックグラウンドですが、これは私の標準的なアプローチですが、小さなヘルパークラスを1つのファイルにまとめています。

したがって、私の現在のプロジェクトの1つでは、クラスはとの間でProduct分割されますProduct.csProductPrivate.cs

于 2010-05-13T19:17:53.397 に答える
1

私は何か他のものを探しています-パブリック/プロテクト/プライベートの問題はこれによって具体的に解決されないかもしれませんが、それは多くのネストされた内部クラスよりもメンテナンスにはるかに適していると思います。

シーケンシャルアルゴリズムに一連のステップがあるように思われるため、1つのステップの実行は、前のステップの実行に依存する場合としない場合があります。このタイプのシーケンシャルステップ処理では、Chain of Responsibility Patternを使用できる場合がありますが、元の意図から少し変形しています。たとえば、次のようなものから始めて、「処理方法」のみに焦点を当てます。

class LargeClass
{
public void DoProcess()
{
  if (DoProcess1())
  {
    if (DoProcess2())
    {
      DoProcess3();
    }
  }
}

protected bool DoProcess1()
{
...
}

protected bool DoProcess2()
{
...
}

protected bool DoProcess3()
{
...
}

}

Chain of Responsibilityを使用すると、これを各ステップの具体的なクラスのセットに分解できます。これは、いくつかの抽象的なステップクラスから継承されます。抽象ステップクラスは、必要な前提条件が満たされている場合に、次のステップが呼び出されることを確認する責任があります。

public class AbstractStep
{
    public AbstractStep NextStep { get; set; }

    public virtual bool ExecuteStep
    {
       if (NextStep != null)
       {
         return NextStep.ExecuteStep();
       }
    }  
}

public class ConcreteStep1 : AbstractStep
{
    public bool ExecuteStep
    {
       // execute DoProcess1 stuff
       // call base
       return base.ExecuteStep();
    }
}

...

public class ConcreteStep3 : AbstractStep
{
     public bool ExecuteStep
     { 
        // Execute DoProcess3 stuff
        // call base
        return true; // or false?
      }
}

これを設定するには、コードの一部で次のようにします。

var stepOne = new ConcreteStep1();
var stepTwo = new ConcreteStep2();
var stepThree = new ConcreteStep3();
stepOne.NextStep = stepTwo;
stepTwo.NextStep = stepThree;

bool success = stepOne.ExecuteStep();

これは、単一のクラスで発生したコードの膨張をクリーンアップするのに役立つ場合があります。これは、過去にいくつかのシーケンシャルタイプのアルゴリズムに使用したことがあり、各ステップを適切に分離するのに役立ちました。明らかに、同じアイデアを条件チェックに適用できます(または、該当する場合は、各ステップにそれらを組み込むことができます)。ExecuteStepメソッドに、ある種の状態オブジェクトを持つパラメーターを取得させることにより、ステップ間で状態を渡すという点で、これにいくつかのバリエーションを加えることもできます。

もちろん、この投稿で本当に気になっているのが単にさまざまなステップを非表示にすることである場合は、はい、各サブステップを、ステップを作成するクラス内の保護されたクラスにすることができます。ただし、何らかの形または方法でライブラリを顧客に公開していて、実行ステップを顧客に公開したくない場合を除いて、これはコードを保守可能にすることよりも小さな懸念のようです。

于 2010-05-13T19:38:54.720 に答える
0

リファクタリングしたメソッドと同じアクセス修飾子を使用してクラスを作成します。部分的なクラスは、同じクラスを頻繁に変更する複数の人または自動化されたコード生成ツールがある場合にのみ本当に役立ちます。複数の編集を同じファイルにマージできないため、ソースコントロールがコードをマッシュするソースマージ地獄を本当に回避します。

于 2010-05-13T19:06:27.577 に答える