4

I've run into the following situation multiple times, and in every case have struggled with the naming.

I want a class to force its children to implement a method, but I want the parent class to be able to override this behaviour if needed. For example:

public abstract class ParentClass {

    public bool debugOverride = false;

    public float GetFloatValue() {
        if (debugOverride) return DebugFloatValue();
        return GetFloatValueFromChild();
    }

    float DebugFloatValue() {
        float someDebugValuesForTesting = 6; // this would be more in reality
        return someDebugValuesForTesting;
    }

    // How do I name this method? 
    protected abstract float GetFloatValueFromChild();

}

This way, consuming classes just call GetFloatValue(). And this class can overwrite its children's behaviour by setting debugOverride to true

My issue, is that the children classes then have this awfully named method in them that is not super clear, they shouldn't care so much that they are children, they should just worry about figuring out the float value.

Perhaps there's a better pattern here that I'm missing?

4 Answers 4

4

This is also known as the Template Method Pattern. Unfortunately there is no commonly accepted naming convention. Name the method based on the use case. The best you can do is look for examples of the Template Method Pattern in the programming language you currently use, and try to infer a naming convention. That is just as valid as coming up with your own naming convention.

When in doubt, consult your team. There might already be an established naming convention if this pattern is used elsewhere in your application.

2
  • Thanks. I haven’t heard of the template pattern but that’s exactly what I am doing.
    – Adam B
    Mar 5, 2021 at 5:53
  • @T.Sar: The template method pattern isn't too complicated. A parent class declares an abstract method. The child class implements the method. The parent class calls the abstract method from another concrete public method. That's all there is to it. Mar 5, 2021 at 13:54
3

Name the method according to what it does and forget whether the method is overridden, abstract, etc.

The caller doesn't need to know whether a method calls overridden methods, calls no methods, or does anything else besides what it says. How it does what it says is an implementation detail which is encapsulated inside the method.

Calling a method DoSomethingByCallingChildMethod is like calling it DoSomethingUsingThePrivateVariable. Nothing outside of the class or method needs to know that. And if the internal implementation of the method changes then the over-specified method name would become incorrect.

The same applies to naming an abstract protected method. The base class tells derived classes what they must implement, not how.

If we want to force the base class to call a method implemented in a derived class we would do exactly the opposite: The concrete method in the base class would call an abstract method which inherited classes must implement.

2

I don't like parent/child for inheritance, this tends to imply composition. In my opinion, it's better to think in terms of base/derived to avoid this ambiguity.

I suspect part of the issue here stems from getting confused by this ambiguity. Your naming seems to imply that you consider the base and derived class as two separate items. But in fact, the derived class is the base class (since inheritance represents a "is a" relationship).
Therefore, any code written in the base class should also be written from the perspective of the derived class.

To use a more casual analogy: the name you've chosen in your example is the equivalent of talking about yourself in the third person.

What you want to avoid here is to have the name reflect that you're thinking from the scope of the base class and consider the derived class as an "outsider". The name you currently chose does just that.

public abstract class BaseClass 
{
    // How do I name this method? 
    protected abstract float GetFloatValueFromDerived();
}

It seems like the right thing to do, because right now you are only writing the base class. But this name will carry over to when you are developing the derived class:

public class DerivedClass : BaseClass
{
    protected float GetFloatValueFromDerived()
    {
        return 0;
    }
}

The name doesn't make sense here, because the implementation of the method in DerivedClass isn't actually fetching this data from somewhere else.

The derived class is deciding this value, it's not fetching it. So the name should reflect that:

public abstract class BaseClass 
{
    protected abstract float GenerateFloatValue();
}

public class DerivedClass : BaseClass
{
    protected float GenerateFloatValue()
    {
        return 0;
    }
}

That being said, the specific method name is highly contextual based on what the method does. There is no one-size-fits-all name here. This kind of pattern is found in all kinds of operations, e.g. GenerateXml, SanitizeInput, TransformData, GetLogger, ...

3
  • 1
    I agree with everything you said. But then how to name the public method in the base class that calls the abstract method?
    – Adam B
    Mar 5, 2021 at 15:59
  • @AdamB: It's contextual. My answer was written under the assumption that in this example, the public method was already the correct public name. Your protected and public methods are two different methods, each with their own purpose. So name them according to their purpose. In my example, you publically get the value which is generated using the class' protected logic. But again, the correct name is contextual.
    – Flater
    Mar 5, 2021 at 16:01
  • Ah I see that makes sense.
    – Adam B
    Mar 5, 2021 at 16:19
0

In this case, DebugFloatValue seems to be the default behaviour, while GetFloatValueFromChild acts as custom derived class specific implementation. Going off that, I suggest using the words default and custom to convey your intent:

public abstract class ParentClass {
    
    public bool debugOverride = false;
    
    public float GetFloatValue() {
        if (debugOverride) return GetDefaultFloatValue();
        return GetCustomFloatValue();
    }
    
    float GetDefaultFloatValue() {
        float someDebugValuesForTesting = 6;
        return someDebugValuesForTesting;
    }
    
    protected abstract float GetCustomFloatValue();
}

A parent class provides default behaviour, so naming the debug function here as default is intuitive. Also using a word like custom hints at the definition being specific to the current class.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.