2

Is it a sign that something is wrong with the code design if you end up with a layer of functions that just forward request to a component? Exposing the component would avoid this but hurts encapsulation.

An example in a C++ like language.

class AnimalManager
{
    public:
    int GetNumAnimalsOfType(EAnimalType AnimalType) { return 77; } 
    
    // Other animal related stuff
}

class Zoo
{
public:
    int GetNumAnimalsOfType(EAnimalType AnimalType) { return m_AnimalManager.GetNumAnimalsOfType(); } 
    
private:
    AnimalManager m_AnimalManager; 
    
    // Other Zoo related stuff
}
3
3

I see this most when people add a layer which might be best practice, but they dont have enough logic to fill it out.

eg in a MVC design

MyController 
{
   GetThings() { return myService.GetThings(); }
}
MyService
{
   GetThings() { return myRepository.GetThings(); }
}
MyRepository
{
   GetThings() { return myOffTheShelfDAL.Get<Thing>("select * from thing"); }
}

So yeah, best practice says all these layers are good, maybe you will fill them out some day, maybe you are just doing them from muscle memory and its not taken any more time. You cant say its bad per-se. But is the same app had had been written with...

MyController 
{
   GetThings() { return myOffTheShelfDAL.Get<Thing>("select * from thing"); }
}

No-one would be saying "Oh! you need a service layer and a repository!!"

4
  • I used to work on a large MVC application that had controllers going right through to the raw data access layer. Query logic is still logic. You would be surprised what pain is caused by hard-coding a SQL query just a little bit different in 5 different places. Hours. Days. Weeks, spent rooting out bugs that would have been prevented by a single method in a repository that encapsulates that query. So, I would say you need a repository in the controller. </rant> Sep 25 at 17:28
  • So, +1 for keeping it simple, but -1 for the code example recommending people hard-code a SQL query in the controller. But I get what you're saying. So +1 anyway. Sep 25 at 17:32
  • 1
    well, extreme example, and i do hate it when people say "YAGNI" when you have already written the dam code. But.. sometimes simple is best
    – Ewan
    Sep 25 at 21:22
  • 1
    I'd say the simple solution wins in an ideal world, but you need the discipline to break things out when they start getting out of hand (and that discipline isn't easy to enforce on a team with more than a few people).
    – casablanca
    Sep 26 at 20:14
3

You cannot make this judgement by looking at the AnimalManager and Zoo classes alone. If AnimalManager is used in other classes, the logic in that class may have originated in Zoo, but was refactored into another class to promote code reuse.

If AnimalManager is only used in Zoo, then yes, it is useless boilerplate code. Any code depending on Zoo is dealing with the abstraction that Zoo provides, which makes AnimalManager an implementation detail transparent to code outside Zoo.

Then again, if AnimalManager has non-trivial logic that reaches out to a database, file system or web service, and the purpose of Zoo is to provide an abstraction that separates other code from data access logic, then what you call boiler plate might be a necessary separation of concerns for code outside Zoo and AnimalManager.

So, this could be a bad design or a good design. Either way, you need to look at the entire Zoo and AnimalManager classes, as well as classes using Zoo and AnimalManager before making this determination.

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.