3

I'm using MVVM + Clean Architecture in my app. And I sometimes don't have any idea if my namings are good enough for each Interface Adapters, Use Cases / Interactors, Entities. For View Models, it's pretty simple. I can just use xxxViewModel as the name. But what about those before? FYI this is my usual namings:

  1. Interface Adapters: I use xxxService for the interface / protocol and for the implementation I use xxxAdapter. And for the prefix, I usually use the bounded context. For example I use AuthenticationApiService / Adapter for the Authentication context API calls, AuthorizationApiService / Adapter for the Authorization context API calls, AppointmentApiService / Adapter for Appointment context API calls, StripeService / Adapter for the Stripe framework, GoogePlacesService / Adapter for Google Places, etc.
  2. Interactors / Use Cases: Since I injected the function instead of the class, I just use the intention of what I want to do as the class name. Eg:
    class SignIn {
        let authenticationApi: AuthenticationApiService
        init(authenticationApi: AuthenticationApiService) {
            self.authenticationApi
        }
    
        // This func will be injected to the view model as the dependency instead of the whole class
        func dataTask(username: String, password: String) -> Observable<UserEntity> {
            authenticationApi.signIn(username: String, password: String)
                .map { decodeToUser(response: $0) }
        }
    
    }

But some of the interactors are grouped together into a big class if there are too many that should belong to a single classification. Like Appointment context interactors (basically a class with the whole CRUD operations in it). For this kind of interactors, I am usually unsure how to name them. For the Appointment one, for example, I just name it AppoinmentHandlerProtocol and AppointmentHandler classes for the protocol and implementation.

  1. Entities: I just use the naming of xxxEntity like UserEntity, AppointmentEntity, CreditCardEntity, etc. Kind of straight forward although I don't know if this is correct or not. Heck, I don't even know whether they are truly entities or just some POJOs or DTOs. Because I classified all of them as Entities (as in Clean Architecture's definition of entity). Although it's not really a Plain Old Object because I at least have to implement Equatable to make the testings easier.
  2. ViewModels: For these classes, I just use the naming like xxxViewModel based on the corresponding Views.

I know that this question is not really an objective one and it's a matter of preference. But I only want to get lots of feedbacks for this.

Thanks in advance.

EDIT:

The example of the code can be seen here: https://pastebin.com/brA83jNy

3 Answers 3

1

Class and method names are supposed to be abstractions that conceal implementation details, not set them in stone. When you let implementation details leak into a name you make it very hard to change that implementation.

Worse you start to brainwash those who come later into thinking this pattern you've enshrined is the only way to solve the problem and must be followed rigorously regardless of any practical considerations.

Does that mean names can only come from the domain? No. Names have many audiences but most significantly the code that knows those names. The names should not reveal to that code things that code should not know.

This isn't about Object Orientation, Functional Programming, or Procedural. This is about abstraction hiding details so any one idea lives in a small place making that idea easy to change.

So when you say things like:

Heck, I don't even know whether they are truly entities or just some POJOs or DTOs

Just don't tell us with a name. That's not something most things working with that object need to know. Done that way if you decide you need to change what it is you don't have to refactor the name everywhere it appears.

Of course this creates a new problem. You now have more classes then you have names. Does that mean you need to eliminate classes? No. Just understand what's driving you here isn't that there is some perfect naming convention that is required by the pattern.

When authors show you a pattern with example names they're often butchering the names to make them into things most book readers will understand. Not necessarily setting a good example.

0

Its normal to question your naming standards. I don't think it matters much tbh, but since you are asking:

Generally speaking including the type in the name, sometimes called Hungarian Notation is usually considered bad.

So, xxxService, xxxEntity, xxxAdapter are code smells to me. If you need to call the User UserEntity, how many different UserXxx classes do you have!

An Exception to the rule would be xxxViewModel which seems to have been adopted in many cases exactly because you need that extra class with the same properties as User plus a few extras for MVVM or MVC patterns.

AuthenticationApiService is particularly bad, with both Api and Service, presumably you have an AuthenticationApi and this is the service it uses? you don't give your full structure but how about making more use of namespaces

myCompany.Authentication <-- business logic class

myCompany.Authentication.Models.xxx <-- various data objects exposed by the service

myCompany.Api.Authentication <-- deployment package with hosted authentication logic

myCompany.Api.Authentication.Client <-- package/class used to connect to the Api

In addition make more use of internal or private classes to limit possible name collisions

11
  • About namespaces, I'm afraid Swift doesn't have it, unfortunately. And also, if you use namespaces, it will evolve to a train wreck / long message chaining code smell pretty fast, IMHO. I do agree that including the type is considered bad. Say, consider this example: If you want to make some classes for Authentication context like so: one Interface Adapter class to handle communication with the API, one Interactor to handle calling the Interface Adapter and convert the response JSON to either a DTO or Entity to be consumed by the the View Model, how will you name them? Aug 21, 2020 at 14:58
  • I would bundle all of those classes in a single client class which returned full objects. User, Order etc. If there was enough code to require sub objects they would be internal to the client assembly or private to the class so they could just be 'TheAdaptor' 'TheInteractor' etc
    – Ewan
    Aug 21, 2020 at 15:17
  • Won't that break Single Responsibility Principle? Aug 21, 2020 at 15:47
  • shouldnt do, add more code to your example so we can see what you are doing with all these classes
    – Ewan
    Aug 21, 2020 at 15:48
  • Well, the whole code will be too big for the comment section (even though it is only one authentication bounded context). So I put it in pastebin here: pastebin.com/brA83jNy Aug 23, 2020 at 7:08
0

Your objects (and public methods) should always be named after some concept from your requirements.

It specifically doesn't matter what architecture or design pattern you decided to use. Your code becomes more readable (and maintainable) the more you reflect the requirements and concentrate on the business value delivered, instead of technical details.

Services, Entities, Interactors, ViewModels, Adapters are all technical words. They have absolutely no place in object or method names. At all.

13
  • Obvious caveat to the first paragraph: helper methods.
    – Flater
    Aug 21, 2020 at 12:17
  • 1
    @Flater If you mean helper methods as in private methods in the object to make code more readable, that's why I've said public methods. If you mean public shared "utility" methods, then I disagree. Those shouldn't exist either, so the first paragraph still applies. Aug 21, 2020 at 12:31
  • 1
    @BawenangRukmokoPardianPutra I don't know UIKit specifically, but if your domain is UI technology, then of course you may use those words. A library for MVC could conceivably use the words Model, View and Controller. But an application whose purpose is not technology, technology-related words are off-limits. Aug 21, 2020 at 15:10
  • 2
    helper methods/classes? burn them with fire
    – Ewan
    Aug 21, 2020 at 15:19
  • 2
    @RobertBräutigam So I've re-read Uncle Bob's Clean Code again and there's this quote: "Remember that the people who read your code will be programmers. So go ahead and use computer science (CS) terms, algorithm names, pattern names, math terms, and so forth. It is not wise to draw every name from the problem domain because we don’t want our coworkers to have to run back and forth to the customer asking what every name means when they already know the concept by a different name." That's a very different approach than yours that says these kinds of technical words don't have any place at all. Aug 23, 2020 at 4:54

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.