当我只希望一些派生类可以访问基类中的方法时,使用什么设计模式

本文关键字:方法 设计模式 什么 基类 访问 希望 派生 | 更新日期: 2023-09-27 18:01:41

我这里有一个独特的问题/情况。尽量让它变得简单。我有一个基类(比如Parent)和一大堆直接从基类(Parent)派生出来的派生类(比如Child1、Child2、childdn)。我想改变基类,并添加一个"AVeryPrivilegedMethod",这将只能访问Child2和Child3,而不是任何其他的孩子(或使其可配置,以便在未来Child5也可以使用它在未来,以最小的变化)。什么样的设计模式/架构模式符合这个要求?

使用语言- c# .

PS:我正在考虑使用InternalVisibleTo,但意识到这在汇编级别应用

当我只希望一些派生类可以访问基类中的方法时,使用什么设计模式

听起来好像你错过了另一个抽象类 (SpecialChild,因为想要一个更好的名字),它继承自Parent,但Child2Child3是从它派生出来的。

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

问自己这个问题:Child2Child3有什么不同,他们自己有共同的行为,但对所有其他孩子有不同的行为?SpecialChild模型的行为,在你的问题中给出的例子将是实现AVeryPrivilegedMethod的地方。

我不明白这与"设计模式"有什么关系——这只是语言特性的问题。c#没有一个语言特性允许这种选择式封装。

我猜你的选择是要么在层次结构中插入一个新的类,BaseWithExtras,从Base派生,并有一些孩子从Base和其他从BaseWithExtras派生,或者停止担心它,只是使方法可用于所有派生类。

您可能想要创建另一个抽象级别:

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

然后每个子类继承相应的类:

// Does not have method
public class ChildA : Parent
// Has Method
public class ChildB: MethodContainer

如果您只能访问基类,我建议在基方法中对类的类型使用反射,并且只允许您想要正确使用基方法的类。如果不是这种情况,并且您有能力修改层次结构或派生类,则只需从您的基类派生另一个类,该类公开您感兴趣的方法,并使您的类从该基类派生。

可能没有好的选择,因为这不是标准级别的保护。这里有一个选项

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

之后,你像这样调用它:

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

这是假设你想要编译器检查(在运行时不使用反射来检查Child2和Child3),并且出于某种原因需要你所说的层次结构。还有其他的答案暗示了一个新的子类级别,这可能是您的情况下的最佳答案。

与依赖注入的旧关联如何(如果需要,您可以稍后更改它以允许其他类访问这些函数)

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

如果这些方法只在某些子类中使用,那么在继承层次结构中包含它们似乎不是个好主意。这里我们想实现的是实现重用,所以通过依赖注入的组合将是一个好主意,但是如果你需要将该方法暴露为类接口的一部分,那么Mixin(如果在c#中可能的话)将是最好的选择。