「プライベート」クラスのC#のクラス修飾子の問題
-
26-09-2019 - |
質問
たくさんの方法があるクラスがありました。
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 class
, 、1つのファイルを持っています MyClass
, 、その他 MyClassConditions
その他 MyClassProcessExecution
.
それらを内部として定義しますか?
私はこれらのクラスが私のプログラム/アセンブリの残りの部分にまったく価値を追加しているとは思わないので、私はそれほど多くの内部修飾子があまり好きではありません。可能であればそれらを隠したいと思います。プログラムの他の部分で有用/再利用可能になるわけではありません。
それらを公開してください?
理由はわかりませんが、ここでこのオプションを許可しました。
他の?
それに名前を付けます!
ありがとう
解決
あなたの最善の策は、おそらく部分的なクラスを使用して、同じクラスに追加された別のファイルに3つのコードの塊を置くことです。その後、クラス自体のみがアクセスできるように、条件付きコードとプロセスコードをプライベートにすることができます。
他のヒント
現在のアセンブリの外で使用されない「ヘルパー」タイプクラスの場合、 Internal
メソッドが複数のクラスで使用される場合に行く方法です。
単一のクラスでのみ使用される方法については、クラスにプライベートにするだけで、実際に他のどこにも使用されていないクラスである場合は、内部クラスを使用します。コードがクラスの(非静的な)メンバーに依存していない場合、コードを静的メソッドにすることもできます。
MyClassを部分クラスとして定義し、MyClass用の1つのファイル、MyClassConditionsのファイル、MyClassProcessexecution用のファイルを作成できます。
たぶんそれは私のC ++の背景ですが、これは私の標準的なアプローチですが、小さなヘルパークラスを単一のファイルにバンドルします。
したがって、私の現在のプロジェクトの1つで、 Product
クラスは間に分割されます Product.cs
と ProductPrivate.cs
私は何か他のものを求めています - 公共 /保護 /プライベートの問題はこれによって具体的に解決されないかもしれませんが、私はそれが多くのネストされた内部クラスよりもメンテナンスにはるかに優れていると思います。
シーケンシャルアルゴリズムに一連のステップがあるように聞こえるため、1つのステップの実行が前のステップの実行に依存している場合と依存しない場合があります。このタイプのシーケンシャルステップ処理は、時々 責任の連鎖 パターンは、元の意図から少し変化していますが。たとえば、以下のようなものから始まる「処理方法」にのみ焦点を当てます。
class LargeClass
{
public void DoProcess()
{
if (DoProcess1())
{
if (DoProcess2())
{
DoProcess3();
}
}
}
protected bool DoProcess1()
{
...
}
protected bool DoProcess2()
{
...
}
protected bool DoProcess3()
{
...
}
}
責任の連鎖を使用すると、これは各ステップのコンクリートクラスのセットに分解され、抽象的なステップクラスから継承できます。抽象的なステップクラスは、必要な前提条件が満たされている場合、次のステップが呼び出されることを確認する責任があります。
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();
これは、シングルクラスで入手したコードの膨満感をクリーンアップするのに役立つ可能性があります。過去にいくつかのシーケンシャルタイプアルゴリズムに使用し、各ステップをうまく分離するのに役立ちました。あなたは明らかにあなたの条件チェックに同じアイデアを適用することができます(または、それが適用される場合、それらを各ステップにそれらを構築します)。また、ある種の状態オブジェクトを持つパラメーターを実行することにより、ステップ間の状態を通過するという点で、これについていくつかのバリエーションを実行することもできます。
もちろん、この投稿で本当に心配していることがさまざまな手順を単に隠すことである場合、はい、あなたのSubstepsのそれぞれを、手順を作成するクラス内の保護されたクラスにすることができます。ただし、何らかの形やファッションでライブラリを顧客にさらしておらず、実行手順にどのような種類の可視性を持たせたくない場合を除き、これはコードを維持できるようにしてから、より小さな懸念事項であるようです。
リファクタリングしたメソッドと同じアクセス修飾子を持つクラスを作成します。部分的なクラスは、複数の人がいる場合、または同じクラスを頻繁に変更するツールを生成するコードを自動化した場合にのみ非常に便利です。ソースが同じファイルに複数の編集をマージできないため、ソースコントロールがコードをマッシュする場所でソースマージ地獄を実際に避けます。