Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a better way to call a derived class's overridden method from its abstract base class?

I have an abstract base class from which many classes are derived. I want derived classes to be able to override a virtual method defined in the base class, but there is complex logic in the base class that determines whether the overridden method is "enabled" at any particular moment.

Consider this code -- one possible solution -- for example:

public abstract class AbstractBaseClass
{
  public bool IsMethodEnabled { get; set; }

  public virtual void DerivedMethod() { }

  public void Method()
  {
    if (IsMethodEnabled)
      DerivedMethod();
  }
}

public class DerivedClass : AbstractBaseClass
{
  public override void DerivedMethod()
  {
    Console.WriteLine("DerivedMethod() was called.");
  }
}

In the example above, IsMethodEnabled is shorthand for more complex logic that determines whether DerivedMethod should be called -- it's code that I want encapsulated in the base class so that I don't have to reproduce it in each derived class.

The design works as intended. If I run this sample code:

AbstractBaseClass a1 = new DerivedClass() { IsMethodEnabled = false };
AbstractBaseClass a2 = new DerivedClass() { IsMethodEnabled = true };

a1.Method();
a2.Method();

...I see exactly one call to DerivedMethod, as expected.

But something rubs me wrong about this implementation. I feel like there must be a more elegant way to handle this. Is there a better way to selectively call a derived class's method implementation from its abstract base class? Is there a design pattern that would better serve me here?

In other words, does the code above "smell"?

like image 592
Michael Avatar asked Sep 13 '11 23:09

Michael


2 Answers

This is a perfectly reasonable implementation.

The main changes I would suggest are:

  • Make the virtual method that implements the functionality protected instead of public
  • Use more appropriate naming for this. Perhaps something more like public void Method() and protected virtual void OnMethod()
like image 123
Reed Copsey Avatar answered Oct 01 '22 21:10

Reed Copsey


I agree with Reed that this is a reasonable implementation.

However, I'd consider the following: who are you trying to protect here? I am all for designing base classes well so that they can be extended easily and safely, but I'm also of the opinion that the developer writing the derived class knows more than the developer who wrote the base class. They might know better than you do whether a given method is "enabled" or not.

like image 38
Eric Lippert Avatar answered Oct 01 '22 19:10

Eric Lippert