Pergunta

in the code base of my job, we use clean architecture standards. So we have controllers, use cases, etc. To name them, we follow this template: {name}{type}, where type is one of the following values: Adaptor, UseCase, Controller, DataAccess, Presenter, and so on. name is a descriptive name of what that type does. For instance, GoogleMapAdaptor, CustomersDataAccess, etc.

My main concern is that this becomes, in some way, repetitive. While reading the code, I get tired of reading {...}UseCase, {...}DataAccess, etc. My coworkers say that we use that naming convention to better understand what type of component you are using, but I find myself doubting if it is really useful.

In addition to that, we use a global ObjectFactory to relate interfaces with implementations, so every use case, controller, and data access in our system, has an interface associated, so names like {name}UseCaseInterface are very common throughout the code base.

What do you think? What naming convention do you use or recommend? Do you think it would be better to strip all that words out?

Foi útil?

Solução

What you're running into here is an issue with the restrictions you (i.e. the developer team) imposed on yourself. You decided to restrict the naming, and now you don't like the restrictive names. There's little to respond to here other than "don't do the thing you don't think is right to do".

This is no different from me labelling all my kitchen shelves, and then realize I have other foodstuffs that have no appropriate label. The solution is to either not have that foodstuff in my kitchen, redo the labeling so it has a place, or just putting it on a shelf and not worrying about the labels.

In other words, either never develop a class that doesn't follow the closed name list, continuously update your name list whenever a new type appears, or stop enforcing this name list altogether.

So we have controllers, use cases, etc. To name them, we follow this template: {name}{type}, where type is one of the following values: Adaptor, UseCase, Controller, DataAccess, Presenter, and so on.

While suffixes like these are ubiquitous and arguably the bread and butter of good naming conventions, I don't think there's any benefit to enshrining precisely which terms you should use.

That's not to say that you shouldn't be consistent in your naming, but defining a closed list is a step too far, in my opinion. Any of your objects might eventually need to be broken down in separate subcomponents when it gets too complex, and having to jump through the hoops of "what name am I allowed to use" is an unnecessary distraction.

To be fair, this is founded on the assumption that all your developers have the self-discipline to name things appropriately and/or communicate with the team hen there's uncertainty.
If you're working in a company where the vast majority of developers are unregulated juniors, and there's no real regulation or oversight of their code or a "devil may care" work attitude, then an enforced naming system may be helpful. But that is a very specific scenario and by no means applicable to developers everywhere, or as a blanket development good practice.

My main concern is that this becomes, in some way, repetitive.

Consistency is repetition at its very core. Repetition isn't sexy, but consistency is highly efficient in terms of categorizing and managing resources from a high-level perspective.
Even in the more relaxed system I proposed above, you'd still be repeating the same suffixes to retain consistency across the codebase.

Going back to the kitchen example, it might be very fun to shop around and buy individual fancy pots to store things in, but you end up with a mishmash of pots. Organizationally speaking it'd be a lot easier to buy one set of the same pots to store all your dry foods in.

My coworkers say that we use that naming convention to better understand what type of component you are using, but I find myself doubting if it is really useful.

I suspect you might be missing the wood for the trees here.

I hear your argument often, coming from developers who are busy developing a very specific feature, and whose opinion mistakenly glosses over the fact that the code should be readable for others (or yourself in the future when you've forgotten most of the internal logic) in a way that they can very quickly get to grips with what this "unknown" class does.

If I have to figure out what each class name does, and each class follows its own individual naming style, it's going to be hard for me to read through an entire codebase (or any group of classes) efficiently.

The proof is in the pudding: I knew exactly what your ObjectFactory does when I read its name, because I know the factory pattern and the name clearly conveys the pattern and thus the intent. If you had named it ObjectGenerator, it would've taken more explanation (or a blind guess) for me to understand what its precise purpose is.

In addition to that, we use a global ObjectFactory to relate interfaces with implementations, so every use case, controller, and data access in our system, has an interface associated, so names like {name}UseCaseInterface are very common throughout the code base.

I struggle with the idea of having a massive ObjectFactory, but that's another discussion. I assume it acts like a DI container and will leave it at that.

The general advice for interface naming is IFoo, not FooInterface. This already helps with cutting down the added bulk (it saves 8 letters, which is not insignificant), on top of making it much easier to distinguish an interface from a class by reading the first letter(s) of the name.

Outras dicas

An object's name (and method names also) should be understandable by anybody involved in the project, not just developers.

Technology, design or architecture patterns are completely secondary, a detail. So naturally they should not be displayed prominently in code. If you do not find your way around without reminders of what architecture pattern you are using, maybe don't use that architecture pattern.

To be honest, what you're describing doesn't sound good at all. Not just the naming, but the architecture itself. Here are a few reasons:

  1. You have a "template". That means you're probably repeating the same structure over and over again. Which means you probably didn't find the proper abstraction yet.
  2. You have a global "ObjectFactory". Everything about that just sounds wrong.
  3. Interfaces which I assume have only one implementation (because of the naming).

So you're right, it shouldn't be repetitive and templated, but it's not just the naming, the problems starts with the design.

Licenciado em: CC-BY-SA com atribuição
scroll top