当我只希望一些派生类可以访问基类中的方法时,使用什么设计模式
本文关键字:方法 设计模式 什么 基类 访问 希望 派生 | 更新日期: 2023-09-27 18:01:41
我这里有一个独特的问题/情况。尽量让它变得简单。我有一个基类(比如Parent)和一大堆直接从基类(Parent)派生出来的派生类(比如Child1、Child2、childdn)。我想改变基类,并添加一个"AVeryPrivilegedMethod",这将只能访问Child2和Child3,而不是任何其他的孩子(或使其可配置,以便在未来Child5也可以使用它在未来,以最小的变化)。什么样的设计模式/架构模式符合这个要求?
使用语言- c# .
PS:我正在考虑使用InternalVisibleTo,但意识到这在汇编级别应用
听起来好像你错过了另一个抽象类 (SpecialChild
,因为想要一个更好的名字),它继承自Parent
,但Child2
和Child3
是从它派生出来的。
Parent
|
|------------------|------------|----------|
Child1 SpecialChild Child4 Child5
|
|---------------------|
Child2 Child3
问自己这个问题:Child2
和Child3
有什么不同,他们自己有共同的行为,但对所有其他孩子有不同的行为?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) { }
}
然后根据子版本的不同,可以注入AllowPrivileges
或NoPrivileges
版本。
// 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#中可能的话)将是最好的选择。