Single Responsibility[^n], Beware the Share[^n], Boyscout Rule[^n]. These are some conventions that guide good practice in software development and I believe naming can benefit from these ideas and other practices. This blog post will discuss class naming using Model View Presenter as the example and show you one change you can do to make your code cleaner and more readable.
MVP[^n] is being used as one example of a design pattern that requires thoughtful naming, this article doesn’t give you direction for what your Model, View or Presenter should do as behaviour, but we can all agree that you usually have an interface for each of these ideas. Infact the main benefits of this article can be taken to naming any grouping of classes and you can reinterpret these ideas for other class naming.
> Many people try to come up with a great name all at once. This is hard and rarely works well. The problem is that naming is design: it is picking the correct place for each thing and creating the right abstraction.
This quote comes from an amazing eight part blog post[^n] that talks about how naming can go through seven stages. As a TLDR; The stages include Missing name, Nonsense naming, Honest naming, Honest and Complete, Does the Right Thing, Intent, Domain Abstracted naming. I believe many people change variable names and go through the stages as discussed maybe not hitting every stage and maybe not getting to the end, but still, variables are renamed often. If these names move towards the right side of this scale, this is movement towards more expressive and readable code.
I want to skip variable naming and move straight on to class naming. Variables get renamed an order of magnitude more often than Classes get renamed. There seems to be a bigger barrier to class renaming, in that it will likely touch more code, affect more people, ruffle more feathers, and so it is done less often. Let’s drop this as an excuse not to strive for clean code and accept class naming as fair game.
Consider a class that implements the interface `TweetsView`, one bad way of naming this implementer is like this `TweetsViewImpl implements TweetsView`. `Impl`?? `Impl`!! Naming an implementation is an important opportunity to convey some meaning about what *that* specific implementation does. It’s lazy to just go with `Impl` and not think about what your class does.
> My interface name describes the behaviour of my class. I can’t think of anything more to add to that, I’ll just use Impl.
Next logical step people usually take is, they know `Impl` is bad naming, but still can’t think of a name because the interface `TweetsView` seems exactly the right name; its a view of the tweets. They avoid the `Impl` code smell with something just as bad: `DefaultTweetsView`, `SimpleTweetsView` or flip it round `TweetsView implements ITweetsView` (this just moves the problem rather than resolves it, but a good hint of what is to come 🙂 ).
You want your classes to be named after the behaviour they exhibit, following the Single Responsibility Principle you should know what this responsibility/behaviour is.
There are two solutions here:
– Only 1 implementer of the interface? Get rid of the interface! Over abstraction is unnecessary and confusing.
– Understand the problem space and name explicitly according to behaviour `TrendingTweetsView implements TweetsView`
Now thinking about class naming and interfaces from another perspective. If we are using MVP and have an interface for `TweetsModel`, `TweetsView`, `TweetsPresenter`. Then these three interfaces are actually intertwined and should be considering as a system. For example, someone new to the code base, seeing a class implementing `TweetsView` could think this is just some type of custom view (not MVP), they could then see the other code implementing `TweetsModel` and still consider this as some other pattern, it’s not until they also notice `implements TweetsPresenter` that they’ll put the three together. It would be nice if we could make this grouping explicit in the code, lets see an example.
“`
public interface TweetsMvp {
interface Model {
…
}
interface View {
…
}
interface Presenter {
…
}
}
“`
Awesome, we have declared our triad of interfaces under one common name. This fixes the problem of understanding the system. Any legacy developer reading this code or reading one of the implementations can see this interface comes from this triad and that it’s clear intention is to be used in the MVP pattern.
“`
public class TweetsModel implements TweetsMvp.Model {
…
}
public class TweetsView implements TweetsMvp.View {
…
}
public class TweetsPresenter implements TweetsMvp.Presenter {
…
}
“`
When we implement the triad of interfaces it further backs up the knowledge that this class is being used in the MVP pattern. Further we have resolved our `Impl` naming issue. We can have our view of the tweets called `TweetsView` and this implements an MVP View of Tweets; `implements TweetsMvp.View`.
This wouldn’t be possible if you just called the individual interfaces `Model`, `View` and `Presenter`. Firstly you usually have multiple MVP interfaces in a codebase and so such generic naming would get very confusing very quickly. Secondly on Android `View` is already used for the UI system and so one of the two `View` classes/interfaces would have to be fully qualified which adds noise to the code.
I hope you find the grouping concept useful even if my poor textual explanation doesn’t get you, then the code example should make it obvious.
Always remember to consider your systems as a whole, what parts of the system are interconnected and should these relationships be made explicit. Naming plays an important role in your codebase and getting it right is hard. If ever stuck, think where you are up to on the seven stages of naming; _missing name, nonsense naming, honest naming, honest and complete, does the right thing, intent, domain abstracted_ and what other entities changing this name might effect.
_____
Sorry / Not Sorry for the viral headline.
![](/blog/content/images/2016/05/sorry-not-sorry-gif.gif)
[^n]: [butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod](https://www.butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod)
[^n]: [programmer.97things.oreilly.com//Beware_the_Share](https://programmer.97things.oreilly.com/wiki/index.php/Beware_the_Share)
[^n]: [c2.com/BoyScoutRule](https://c2.com/cgi/wiki?BoyScoutRule)
[^n]: [en.wikipedia.org/wiki/Model-view-presenter](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93presenter)
[^n]: [arlobelshee.com/naming-is-a-process](https://arlobelshee.com/tag/naming-is-a-process)