Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Abstract Base or Helper Class

I just today learned a little about Composition over Inheritance. I was wondering if I should apply the concept to something I wrote recently.

We previously had two classes that were almost identical, aside from a couple small differences. They contained some basic database access features, but operated on different (but related) object types. So we previously had class that were structured something like this:

class BallMillDBHandler{

    public BallMillDBHandler(){ ... }

    public void InsertTool(BallMill tool) { ... }
    public BallMill QueryTool(string toolID) { ... }
    public void UpdateTool(BallMill tool) { ... }
    public void DeleteTool(string toolID) { ... }
}

class DiamondToolDBHandler{

    public DiamondToolDBHandler(){ ... }

    public void InsertTool(DiamondTool tool) { ... }
    public DiamondTool QueryTool(string toolID) { ... }
    public void UpdateTool(DiamondTool tool) { ... }
    public void DeleteTool(string toolID) { ... }
}

I took the majority of near-duplicated methods and refactored them out into a BaseToolDBHandler() class, and inherited it from the other two, providing a few abstract methods and properties to handle differences in accessing the database parameters themselves.

Would it make sense to make the BaseToolDBHandler a helper class instead, contained within the database accessors, and provide them a common interface the previously abstract properties/methods? Or should I leave it as a case of inheritance?

like image 693
KChaloux Avatar asked Sep 25 '12 14:09

KChaloux


2 Answers

This looks like a scenario that would benefit both generics and inheritance via a base class / interface.

class DBHandler<TTool> where TTool : ToolBase // or ITool
{
    public DBHandler(){ ... }

    public void InsertTool(TTool tool) { ... }
    public TTool QueryTool(string toolID) { ... }
    public void UpdateTool(TTool tool) { ... }
    public void DeleteTool(string toolID) { ... }
}

If you need to, you could make a base (optionally abstract) class, or an interface to use as a type constraint that would guarantee certain members that you needed the tools to have inside the method bodies.

Examples:

var handler = new DBHandler<BallMill>();
BallMill value = handler.QueryTool("xyz");
value.SomeProperty = "New Value";
handler.UpdateTool(value);
like image 165
Dan Avatar answered Nov 03 '22 15:11

Dan


Inheritance does tend to be over-used, but this seems like an appropriate case for it. In many cases people just see duplicate code and think "I'll use inheritance to remove the duplicate code through a base class." In reality, most duplicate code can be refactored into another class entirely that is used in several places. Usually the classes using it aren't "related" they are doing two entirely different things and just happen to share the need to do some (or some series of) small tasks.

Inheritance should be used when classes when you can really say that the class class "is" an instance of the base class, not just some class that needs access to a bunch of methods defined elsewhere. In your particular case, it's clear that both classes are DB handlers. At their crux, both of them are serving the same general goal, but they are two different possible implementations of that goal. The only problem that I could see here (given that you haven't shown the contents of any of the methods) is that you may be able to combine both classes into a single class, but we would need to know more about the details to know if that's either possible or preferable.

like image 27
Servy Avatar answered Nov 03 '22 15:11

Servy