简体   繁体   English

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

[英]What design pattern to use when I want only some derived classes to have access to a method in base class?

I have a unique problem/situation here.我在这里有一个独特的问题/情况。 Trying to make it as simple as possible.试图让它尽可能简单。 I have a base class (say Parent) and a whole bunch of derived classes (say Child1, Child2..ChildN) directly deriving from the base class (Parent).我有一个基础 class(比如父级)和一大堆派生类(比如 Child1、Child2..ChildN),它们直接派生自基础 class(父级)。 I want to change the base class and add a "AVeryPrivilegedMethod" which will only be accessible to Child2 and Child3 and not to any other Children (or make it configurable such that in future Child5 can also use it in future, with minimal changes).我想更改基础 class 并添加一个“AVeryPrivilegedMethod”,该方法只能由 Child2 和 Child3 访问,而不能由任何其他儿童访问(或使其可配置,以便将来 Child5 也可以在将来使用它,只需进行最小的更改)。 What design pattern /Architectural pattern will fit this bill?什么样的设计模式/架构模式适合这个法案?

Language used - C#.使用的语言 - C#。

PS: I was thinking about using InternalVisibleTo but realize that this gets applied at the assembly level PS:我正在考虑使用InternalVisibleTo但意识到这会在装配级别应用

I don't see what this has to do with "design patterns" -- it's just a matter of language features.我不明白这与“设计模式”有什么关系——这只是语言特性的问题。 C# does not have a language feature that permits this sort of pick-and-choose encapsulation easily. C# 没有语言特性可以轻松实现这种选择封装。

I guess your options are to either insert a new class in the hierarchy, BaseWithExtras , deriving from Base , and have some children derive from Base and others from BaseWithExtras , or to stop worrying about it and just make the method available to all derived classes.我猜您的选择是在继承自Base BaseWithExtras Base而另一些孩子则从BaseWithExtras ,或者停止担心它并让该方法可用于所有派生类。

You would want to make another level of abstraction:您会想要进行另一个抽象级别:

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

Then each child class inherits the appropriate class:然后每个子 class 继承相应的 class:

// Does not have method
public class ChildA : Parent

// Has Method
public class ChildB: MethodContainer

It sounds as though you're missing another abstract class ( SpecialChild for want of a better name) that inherits from Parent but from which Child2 and Child3 are derived.听起来好像您缺少另一个抽象 classSpecialChild表示想要一个更好的名字),它继承自ParentChild2Child3派生自其中。

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

Ask yourself this question: what is different about Child2 and Child3 such that they share common behaviour themselves, but have different behaviour to all of the other children?问自己这个问题: Child2Child3有什么不同,以至于他们自己有共同的行为,但对所有其他孩子有不同的行为? SpecialChild models that behaviour and in the example you gave in your question would be the place to implement AVeryPrivilegedMethod . SpecialChild对该行为进行建模,并且在您在问题中给出的示例中将是实施AVeryPrivilegedMethod的地方。

If you only have access to the base class, I'd say to use reflection on the type of the class in the base method, and only allow classes that you want to correctly use the base method.如果您只能访问基本 class,我会说在基本方法中对 class 的类型使用反射,并且只允许您想要正确使用基本方法的类。 If that's not the case, and you have an ability to modify the hierarchy or the derived classes, just make another class derived from your base that exposes your method of interest, and make your classes derive from that.如果不是这种情况,并且您有能力修改层次结构或派生类,只需从您的基类派生另一个 class 以公开您感兴趣的方法,并使您的类从中派生。

There are probably no good options, since this isn't a standard level of protection.可能没有好的选择,因为这不是标准的保护级别。 Here's one option这是一个选择

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

Later, you call it like this:后来,你这样称呼它:

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

This is assuming that you want compiler checking (not using reflection at runtime to check Child2 and Child3), and for some reason need the hierarchy you stated.这是假设您想要编译器检查(不在运行时使用反射来检查 Child2 和 Child3),并且由于某种原因需要您声明的层次结构。 There are other answers that suggest a new level of subclass, which may be the best answer in your situation.还有其他答案表明新级别的子类,这可能是您情况下的最佳答案。 If not, this might help.如果没有,这可能会有所帮助。

How about good old association with Dependency Injection (so you can change it later if needed to allow other classes to access the functions).与 Dependency Injection 的良好旧关联如何(因此您可以稍后在需要时更改它以允许其他类访问这些函数)。

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) { }
}

Then depending on the Child, you can inject the AllowPrivileges or NoPrivileges version.然后根据 Child,您可以注入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

If those methods are going to be used in only certain child classes including them in the inheritance hierarchy doesnt look like a good idea.如果这些方法仅用于某些子类,包括 inheritance 层次结构中的子类,这看起来不是一个好主意。 Here what we want to achieve is implementation reuse so composition through dependency injection would be a good idea, however if you need to expose that method as a part of your classes interface then Mixin(if it was possible in C#) would have been the thing to go for.在这里,我们想要实现的是实现重用,因此通过依赖注入进行组合将是一个好主意,但是如果您需要将该方法作为类接口的一部分公开,那么 Mixin(如果在 C# 中可能的话)将是合适的至 go 为。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当您需要派生 class 字段值但您只有基本 class 字段变量时使用什么设计模式? - What design pattern to use when you need derived class field values but you only have base class field variables? C# 仅在选定的派生类中使用基类方法 - C# use base class methods in selected derived classes only 当我在基类型中具有另一个属性的 BsonId 属性时,有没有办法在派生的 class 中使用“Id”属性? - Is there a way to use an “Id”-property in a derived class when I have the BsonId-attribute for another property in the base type? 使用派生的 class 对象访问基本 class 方法 - Access the base class method with derived class objects 防止从派生的 class 访问基本方法 - Preventing access to base method from derived class 我有一个基类实例的XML,想反序列化为派生类实例 - I have an XML of a base class instance, want to deserialize to derived class instance 将父级和子级类与子方法一起使用的设计模式是什么? - What design pattern to use parent and child class with child method? 尝试实现运行时多态时如何访问派生类中基类的Protected变量? - how to access the Protected variable of base class in derived classes when try to achieve run-time polymorphism? 我有一个基类。 如何为正确的派生类调用正确的方法? - I have a base class. How do I call the right method for the right derived class? 如何在基类中表示方法执行的状态而又不影响派生类中的实现? - How can I represent state of method execution in base class without affecting the implementation in the derived classes?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM