1

私はここに独特の問題や状況があります。できるだけシンプルにしようとしています。私は基底クラス(親と言う)と、基底クラス(親)から直接派生した派生クラス(Child1、Child2 ..ChildNと言う)の全束を直接持っています。私は基本クラスを変更し、Child2とChild3のみにアクセス可能で、他の子にはアクセスできないようにする(または今後Child5が将来も最小限の変更でそれを使用できるように設定可能にする) "AVeryPrivilegedMethod"を追加したい。どのようなデザインパターン/建築パターンがこの法案に適合するか?一部の派生クラスのみをベースクラスのメソッドにアクセスさせたいときに使用するデザインパターンは何ですか?

使用言語 - C#。

PS:私はInternalVisibleToを使用しますが、これは、アセンブリレベルで適用されることを実現することを考えた

答えて

3

あなたが別の抽象クラスにを逃しているているようですねParentから継承されるが、Child2およびChild3が由来するものである(より良い名前の欲しいものとしてSpecialChild)。

 Parent | |------------------|------------|----------| Child1 SpecialChild Child4 Child5 | |---------------------| Child2 Child3 

は自分自身にこの質問をする:何が違う程度Child2Child3、それらが共通の動作そのものを共有するが、他の子供たちのすべてに異なる動作を持っていること? SpecialChildのモデルでは、あなたの質問にあなたが与えた例の行動はAVeryPrivilegedMethodを実装する場所になります。

4

私は、これは「デザインパターン」に関係しているか見ていない - それは言語機能の問題です。 C#には、この種の選択と選択のカプセル化を簡単に許可する言語機能はありません。

は、私はあなたのオプションがBaseから派生する、階層、BaseWithExtrasに新しいクラスを挿入して、いくつかの子供たちがBaseWithExtrasからBaseと他人から派生持っているか、それを心配停止するだけの方法を利用できるようにするのどちらかであると思いますすべての派生クラス。

+0

私はこれまで、他のクラスを「安全」対策として特権的な機能に限定することを考えていましたが、実際には意味がありません。 mquanderが言ったように、ただ2つのクラスを作るか、誰かがサブクラスにそれを使うようにするほうが良いです。サブクラスかベースクラスのどちらにアクセスするかを決めることができますが、コードのどこかでその関数を使うクラスを指定する必要があります。あなたはそれを偶然、あるいは子供の授業と呼ぶのを恐れていますか?ユーザーがそのクラスにプラグインを書き留めないようにしようとしていますか? – voodoogiant

3

あなたは抽象化の別のレベルにしたいでしょう:

public class Parent { } 
public class MethodContainer : Parent { public void SomeMethod() { } } 

そして、それぞれの子クラスが適切なクラスを継承します。

// Does not have method 
public class ChildA : Parent 

// Has Method 
public class ChildB: MethodContainer 
0

ベースクラスにしかアクセスできない場合は、ベースメソッドのクラスの型についてリフレクションを使用し、ベースメソッドを正しく使用するクラスのみを許可するとします。そうでなければ、階層や派生クラスを変更する能力があります。興味のあるメソッドを公開する別のクラスを基底から派生させ、それからクラスを派生させてください。

0

これは標準的な保護レベルではないため、おそらく良いオプションはありません。

Child2 c = new Child2(); 
Parent.AVeryPrivilegedMethod(c); 

これは(CHILD2とChild3をチェックするために、実行時にリフレクションを使用していない)を使用すると、コンパイラのチェックをしたいと仮定し、何らかの理由でされています。ここでは

class Parent 
{ 
     private void AVeryPrivilegedMethod() {} 
     public static void AVeryPrivilegedMethod(Child2 c) { ((Parent)c).AVeryPrivilegedMethod(); } 
     public static void AVeryPrivilegedMethod(Child3 c) { ((Parent)c).AVeryPrivilegedMethod(); } 
} 

その後、あなたはこのようにそれを呼び出す一つの選択肢ですあなたが述べた階層が必要です。あなたの状況で最高の答えかもしれない新しいレベルのサブクラスを提案する他の答えがあります。そうでない場合は、これが役に立ちます。

0

依存関係注入との良好な関連性について(他のクラスが関数にアクセスできるようにするために必要に応じて後で変更することができます)

public class Parent { 
    private PrivilegedFunctions p; 
    public Parent(PrivilegedFunctions inP) { p = inP; } 
} 

public interface PrivilegedFunctions { 
    void SomeFuncHere(); 
} 

public class AllowPrivileges : PrivilegedFunctions { 
    public void AllowPrivileges() { } 

    public void SomeFuncHere() 
    { 
     // Actual implementation 
    } 
} 

public class NoPrivileges : PrivilegedFunctions { 
    public void NoPrivileges() { } 

    public void SomeFuncHere() 
    { 
     // No implementation 
    } 
} 

public class Child1 : Parent { 
    public Child1(PrivilegedFunctions inP) : base(inP) { } 
} 

は、子に応じて、あなたはAllowPrivilegesNoPrivilegesバージョンを注入することができます。

// Child with privileges 
Child1 with_priv = new Child1(new AllowPrivileges()); 
with_priv.SomeFuncHere(); // Does privileged operation 
// Child without privileges 
Child1 without_priv = new Child1(new NoPrivileges()); 
without_priv.SomeFuncHere(); // Does nothing 
0

これらのメソッドが継承階層に含まれている特定の子クラスのみで使用される場合、そのアイデアは良い考えではありません。ここで私たちが達成したいのは実装の再利用です。したがって、依存関係注入による構図は良いアイデアですが、クラスインタフェースの一部としてそのメソッドを公開する必要がある場合は、Mixin(C#で可能だった場合)行きたい