TODO: Explore to cover Protocol Witness
Protocol Naming
While doing some work using the MVVM+Coordinators acchitecture, one of the first problems I have faced was naming, more precisily what to call to ViewModels, both their types (protocol) and implementation classes.
Of course we can use MVVM without the use of protocols to typify the ViewModels. However, there is n+1 articles out there advocating the vantages of Protocol-Oriented Programming.
One of the rules I'm following while using MVVM is refer all the ViewModels through their protocol type.
This raises, immediatly, the question, how to name both the ViewModel's protocol and complient classes.
My main rule was try to comply mush as possible with the official recomendations and best practices.
Apple's guidelines for protocols are:
Protocols that describe what something is should read as nouns (e.g. Collection). Protocols that describe a capability should be named using the suffixes able, ible, or ing (e.g. Equatable, ProgressReporting).
In our case, that is to name ViewModels, we should read them as nous because their role are being types.
First decision
Which one should keep the canonical name, the protocol or the class?
Supposing we have a ViewModel for UserPreferences. Naturally, we will have a UserPreferencesViewModel. Is this UserPreferencesViewModel that I consider the canonical name. So, should UserPreferencesViewModel be the name of the protocol and call something else to all the classes that comply? Or should we call the protocol UserPreferencesViewModelProtocol (or other thing, such: Type) and the UserPreferencesViewModel the default class?
This decision is pretty easy to make. While the protocol reference will be spread all over the code, the class name will be used just once, during their init. So, it's the protocol that should uise the canonical nomenclature. This is consistent with Apple's rules and practices.
Second decision
This is the tough one. What to call the classe that actually is our viewModel. One of the Swift code conventions is, do not use abbreviations. This immediatle rule out the Imp / Impl suffix.
In this type of cases, where we end up one having one implementions (other than the fake one for tests), are the difficult ones. When this happens, I tend to naturally call then as the "default" or "standard" viewModel. However, using those words as prefix doesn't make to much sense and also hurts the readability/searchability of all different kind of classes for a specific feature. Imagine we will have the UserView, UserViewController, UserViewModel, User, UserService and StandardUserViewModel! Doesn't seems tidy.
I also didn't found a nice suffix, something that reads naturally. The most natural naming always ends with "view model".
After several tries, I end up calling it "SomethingDefaultViewModel". So, I'm still using the "default" word but move it from being a prefix to be in the middle of the name, just before the "ViewModel". In this particular example, I would use UserDefaultViewModel. Some could argue it's not perfect or that is worse than other options. Fair, but for me it works and fulfill all my rules.