0

As I have been answering questions related to object-oriented design and how to go about reducing the amount of classes to make sure that there is not a lot of "class clutter" and code repetition I have started doubting myself as to how much encapsulation is too much encapsulation and by the same token how much encapsulation is not enough encapsulation.

Here is a specific scenario. One of the most painful ones, which I have come across a few times already, is when one is trying to retrieve few pieces of similar data from the database and as a result the row objects and repositories look very similar as well.

This begs a question as to how much should one encapsulate. I guess for the entity objects one could create a base class, but what about the repositories?

Most of the mapping code is going to be similar but are you really going to put half of mapping in the base class and half of it in the subclasses? Not that you can't but for me personally it is a code smell in a sense that your base class is supposed to facilitate the creation of its derived classes but not help them with their method implementation. It should allow them to override methods but not give them half of the mapping logic and then let them implement the rest.

Would you rather completely separate the repositories even if they were a bit similar in data mapping (the entity objects would be different for each repository) or would you try to base class some of it?

Basically my struggle is this:

Would you rather let each repository encapsulate all that it needs for itself even if some of it might be similar to other repositories?

Or

Would you rather base class it by getting rid of the duplication and as a result have that strange design where a base class provides half the logic and the subclasses take care of the rest?

Example:

public class RepositoryA
{
    private EntityObjectA load()
    {
         // load from db by calling a stored procedure
         // once loaded we do mapping
     }
 }

public class RepositoryB
{
    private EntityObjectB load()
    {
        // load from db by calling a stored procedure
        // once loaded we do mapping
    }
}

public class RepositoryC
{
    private EntityObjectC load()
    {
        // load from db by calling a stored procedure
        // once loaded we do mapping
    }
}

public class EntityObjectA
{
    public string field1 { get; set; }
    public string field2 { get; set; }
    public string field3 { get; set; }
}

public class EntityObjectB
{
    public string field1 { get; set; }
    public string field2 { get; set; }
    public string field3 { get; set; }
    public string field4 { get; set; }
    public string field5 { get; set; }
}

public class EntityObjectC
{
    public string field1 { get; set; }
    public string field2 { get; set; }
}

Now then would you make a baseclass as an EntityObjectBase?

That I can still understand but what about the repositories?

I mean you can pretty much see mapping is going to be pretty similar but does it worth trying to combine them?

How far do you go with encapsulation because in this case there will be some code repeat if we don't, but if we do we get a weird type of design.

2

Not that you can't but for me personally it is a code smell in a sense that your base class is supposed to facilitate the creation of its derived classes but not help them with their method implementation.

I'm not sure if this assertion is necessarily true.

I can think of many examples where it's accepted for base classes to provide functions which are useful to the internal implementation of classes extending them. Perhaps a trivial example would be something like a toString() or equals() method which is often useful to the internal implementation of child classes. Also, the protected access modifier is explicitly intended for the scenario where a function should be accessible to a child internally but not externally.

In your case I think a combination of a template method pattern and generics could be used. The load function would belong to the abstract class, it would call a protected getStoredProc() function (not implemented in the abstract class), and return a generic type. Then the actual implementation only has to implement the getStoredProc() method and define the type.

  • This is actually pretty cool I have thought of doing the template method pattern myself but missed out on adding generics to it. Will implement this and see how it goes. Thanks for your help! – AvetisG Mar 22 '15 at 14:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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