Naming things is hard
By: Josh Bruce
Tags: Coaching, Agile, Software Development

Kevlin hits on sort of the fundamental thing about object-oriented design though, we’re supposed to be able to name things what they are. So, what’s really going on here from a UI perspective?

We have n products available. We want to list the products. We probably want to show a single product.

Right.

class Product {} class ProductList {} class ProductDisplay {}

Of course, these are just the views (and one model, I know its the model because it doesn’t a suffix; it isn’t the modifier for a different business object). So, what do we do about the controller part of model-view-controller/presenter/manager architecture?

Normally?

class Product {} class ProductList {} class ProductListViewController {} class ProductDisplay {} class ProductDisplayViewController {}

Agglutination for the win.

What would be the benefit in doing something like this?

Partially if the files are sorted alphabetically…there you go…pretty well organized. (You want an interesting exercise? Have all your files sort on last modified date instead of name. See how quickly you can find things. Without using search and your knowledge of the file structure of the system.)

If I’m looking for the view controller that helps display a product, I can scan down the left to find “Product” hop to the right to find “View Controller,” then zero-in on the middle bit for “Display.”

Another benefit to this comes in the form of file search.

I don’t remember the full name of that view controller, but our convention says to tack on “view controller” at the end; so, if I bring up the file search function in my IDE and start typing “ViewControll…” I will get a list of all the view controllers in my application, at which point I can scan down the left for the model, then hop to the middle for the specific view I’m looking for.

Luckily, I don’t know how to search by file name in my IDE. So, I have to solve the pain of looking for files in other ways…most importantly by writing less code (or trying to anyway).

It’s actually become something of a kata with me in fact, to the point I don’t lament not being able to search to find a file within a project; instead, if I can’t find it, I say to myself, “Well that’s obviously in the wrong place or is doing two things instead of one,” and move it to the first place I looked or find the point of separation (leaving part where it was and moving the other part where I first looked).

Most of this practice comes from constraints and working in a call center at a bank before I owned a laptop and not having any development tools outside of Notepad on my computer there. (Actually developed an entire CMS this way. You’d be surprised how simple, yet solid and complete a CMS can be with little to no code and under that many constraints — coding between “tech support calls”. I used to email the code to myself at the end of the day so I could continue working on it at home — took less than a minute; and I had no way of compressing it.)

One of the conventions we (developers and framework authors) established is to use folders to sort of separate things out, but we do so based on the abstract architecture, not the domain architecture:

/Models

Product.nolang

/Views

ProductList.nolang

ProductDisplay.nolang

/Controllers

ProductListViewController.nolang

ProductDisplayViewController.nolang

Of course, this brings up the interesting point made by “Uncle” Bob Martin who asserted that the architecture should not be hidden behind the implementation or framework. When we look at the root of our projects we should be able to glean something about the software being developed, not the environment in which the software is being built or run.

I took this to heart.

I also took to heart the advice from DHH as referenced by Adam Wathan regarding “more controllers” and decided to give it a go with the 8fold Platform (this lots of controllers thing is something that sorta comes naturally to developing native apps for iOS and macOS because all the tutorials and examples do the same, we don’t really have a lot of that on the wild-wild-web).

The goal was a controller per GET route.

Our working example would end up looking something like this in the beginning:

/Product

Product.nolang

List.nolang

Display.nolang

ListController.nolang

DisplayController.nolang

Not bad. One of the things I love about the Apple development universe though is the existence of the UI Kit. As long as I’m not doing something too crazy, I don’t ever need to actually create a view…just view controllers that pass data to views. We do try to solve this with various template engines but, if you’ve been following along with 8fold UI, I think there might be a better, or at least a different, way that has benefits over what we’re accustomed to. So, we can get rid of the views because the controllers will pull them from a higher level library:

/Product

Product.nolang

ListController.nolang

DisplayController.nolang

At which point we can do this:

/Product

Product.nolang

List.nolang

Display.nolang

Now, there is frustration that can come from this setup…if I want to change where these files are for some reason, there might be a naming conflict and changing the names or location might require a namespace change. But, I think we’re okay for now.

If you remember from I can haz View Controllers I said the naming convention I was going to try was something like this:

{resource-name}{verb?}{controller-type}Controller

I tried that, for about a day, it turned into this:

{controller-type-abbr}{resource-name}{verb?} // translates to

VCProductList

The nice part here definitely came from taking advantage of alphabetical sorting. All the models would lack the “VC” prefix. And, I did have another controller type called “Resource,” which would be “RC”. But now it looks like I’m settling on:

{verb}

The methods in the resource controllers are so short that having separate controllers and files for each seems like it would be annoying. Too many files. I think this might actually be the wrong way to look at things, again, going back to Adam and DHH, more controllers, man!

Just about every route pattern can have a controller. Each controller has a method, which is a verb. So, one controller for each non-get route would look like this:

/Product

Product.nolang

...

Post.nolang

Instead, I’m thinking this would be okay (I will switch to the Laravel verbs for this one, because it’s actually pretty decent, I think):

/Product

Product.nolang

Create.nolang

Store.nolang

Index.nolang

Show.nolang

Edit.nolang

Update.nolang

Delete.nolang

The only verb choice and combination that really throws me with Laravel is “Create”. The general flow goes like this:

Create (view form) -> Store (post form) // Now you have something to display so you can

Index (view all) -> Show (show one) // Now that you have stored and can display one you can

Edit (view form) -> Update (post|patch form) // And, last but not least you can

Delete (post|delete form)

(Remember, we need the names to be unique because by convention all the methods are in one class.)

The method after the pipe is the RESTful method you can use in Laravel, but forms on the Internet only allow for two methods, GET and POST; so, this is a way to tell Laravel, “I want you to use this other controller for this form method; or, the same route and controller with a different method; or, for our purposes, the same route, a different controller and method.”

Given the way I work with and think about web forms, UX, and language, what I really want is something like this:

New (view form) -> Save (post form) Index (view all) -> Detail (show one) Edit (view form) -> Save (post|patch form) Delete (post|delete form)

“Create,” as a verb, is the act of creating something that did not exist. Choosing it as the verb almost forces you to choose the word “Store” to tell the computer when to write it to disk (and telegraph that to yourself when reading). But, they’re too close to another, in my opinion. New and Save (or even New and Store), I think work better.

Having said that, most users are not accustomed to hearing the term “Store” in reference to saving something for future use. Basically, what I’m saying is, part of the learning curve for Laravel is learning a different vernacular than what we are accustomed to in desktop applications (and what we will most likely label things in the UI).

File -> New -> Save

File -> Open (recent)

File -> Edit -> Save (changes)

Delete (Move to Trash)

Further, the method implementation for both saving after an update and saving after creating something new tend to be very similar for me, and we can still call a different controller method (or entire controller) if we want to, based on the RESTful post method of the form. Back to the file list (alphabetized this time)!

/Product

Delete.nolang

Edit.nolang

Index.nolang

New.nolang

Product.nolang

Save.nolang

Show.nolang

I might even go so far as to change the “Index” and “Show” to something more like the Apple UIKit world, with “Master” and “Detail” from UISplitViewController.

/Product

Delete.nolang

Detail.nolang

Edit.nolang

Master.nolang

New.nolang

Product.nolang

Save.nolang

I’m not sure what will happen if I end up in a situation where I have more than one business object in a folder (maybe a sub-folder, but I shudder at the notion). But, I don’t think I will run into the name collision problem because the business object is a noun while all the controllers are verbs…except for “Master”; however, I’m not sure I’ll ever create an app that will have an object called “Master.”

From a user perspective, specifically a new developer coming on to the project, I think this will work out pretty well.

“I need you to change the way the product details page is displayed.” This would be a relatively uncontrived way of asking the new person to do that. The question is, how much decoding needs to happen between my saying that and the project files themselves?

With the older structure, or the default Laravel setup, I would need to translate that to the architecture of the framework…possibly a lot of decoding. With this new architecture, I should be able to tease it out from the keywords.

I go to the package. Go to the “Product” directory. “Hey, there’s a file called ‘Detail’, I wonder if that’s it?” Open the file. It’s a Controller and the only public method returns a view. Pretty sure this is it. (I don’t have to translate the lexicon of the business to the lexicon and hierarchy of my application.)

(The caveat here being, once the new person gets there it might not be as obvious what to do next. But I, as the “lead developer” am not spending my time giving someone directions on how to navigate the vast, disparate terrain of the project compared to the words I’ve spoken; instead, we can get down to talking about the non-obvious things inside the actual code they’re trying to change.)

I’ll give this a shot and let you know how it goes.