Some Rules For Good Naming

This Grumpy Programmer mailing-list essay got me thinking:

There is one point of contention I have with Laravel — some of the naming conventions that have causes numerous Twitter flame wars and blog posts. I speak, of course, about facades. … [T]he facade thing is a warning to remain vigilant and do your research into what everyone else calls something. Common vocabulary is critical when it comes time to solve difficult problems.

I completely agree with the emphasis on using a common vocabulary. One issue here is that naming things properly is very, very hard. It is one of the only two hard problems in programming.

Are there any rules (even rules-of-thumb) that can we use to make it easier to pick good names for the classes and concepts in our projects?

What’s In A Name?

Above all, a good name makes it obvious what we are describing. It provides clarity by itself without the need for further explanation.

However, because a word can be ambiguous, we have to pick the proper context for the use of a name. Using the right context when picking a name is paramount.

Unfortunately, in programming, there may be overlapping contexts. Giving a name to a domain class or concept can be especially difficult because of this overlap. Do we name an element for what the domain experts call it in their normal day-to-day work, or for its layer in the overall system, or for the pattern of its design?

Not A Novel Context

The first thing we have to remember, then, is that we are not writing a novel in English. Instead, we are writing software instructions. We are writing these instructions in something other than a normal human language. We are writing these instructions for a computer, and simultaneously writing them for human readers of that programming language.

With that in mind, I suggest the following order of priority for picking the proper context for a name:

  1. First is the vocabulary, common idioms, and core resources of the programming language itself. If the language itself, its core classes and methods, or the common expressions of its professional programmers associate particular vocabulary words with a concept, activity, or behavior, we should choose from among those words first when attempting to pick a name.

  2. Second is the vocabulary and common idioms related to previously identified patterns of software design. If there is a software design pattern that matches the concept we are trying to express, its name should be our next-best choice.

  3. Third is the vocabulary, idioms, jargon, and slang related to the domain. If there is no appropriate word from the programming language, and no relevant software design pattern, then falling back to the domain for the naming context is our next priority.

  4. The absolute last context should be words from normal everyday interactions. We use these words only after exhausting the other three contextual options. This is the least-appropriate context for picking a name.

This priority order is probably the opposite of what many would prefer. As human beings, we are more fluent and familiar with the vocabulary of our everyday writing and speech. It took many years of hard work to acquire that vocabulary in the first place, and we are unwilling to do additional hard work to acquire yet another vocabulary that applies more appropriately the context of programming. We would prefer to reuse the words we already know, instead of learning how to apply new words.

Even so, to be good at communicating the concepts of software programming to other programmers, it is incumbent upon us as professionals to expand our vocabulary. We must learn these new terms and their proper use. This is especially difficult with patterns of software development.

Patterns Are Defined By Behavior

When it comes to patterns, we have to remember that the patterns themselves pre-exist their names. The names were applied only after seeing the same patterns over and over again in many different programs. This means that it is the behavior of a construct that determines what its appropriate pattern-related name should be. If we write code like this …

<?php
class Foo
{
    public function newInstance($bar)
    {
        return new $bar;
    }
}
?>

… and we never mention the word “factory”, the code is still representative of the Factory pattern. A rose by any other name may smell as sweet, but if we call it a daisy then nobody will be able to guess that it has thorns. Similarly, a “factory” by any other name still creates and returns objects. Calling the above construct anything other than “factory” (or a factory-related name) removes clarity instead of providing it.

Picking The Closest Pattern

As a related issue, it’s not enough to look through pattern definitions and find one that is “close enough.” We must find the best one we can that matches the most parts of the concept we are trying to express in a name. This can be a lot of effort.

By analogy, we should not call a “motorcycle” a “bicycle” and expect to be understood fully. Yes, a “motorcycle” matches up with a “bicycle” in important ways: they both have two wheels, we steer and brake with our hands instead of our feet, we sit on a seat above the frame, and so on.

But for all their similarities, they are clearly different things. Better to call a motorcycle by its proper name so that we impart better understanding. Likewise, better to call something a Proxy instead of a Facade when appropriate.

Avoid Claiming A Special Context

When picking a context for a name, it is very tempting to define our own special context that lets us pick a name we prefer, perhaps for marketing or other non-technical reasons. We need to avoid this temptation.

Imagine if General Motors, in its marketing materials, called a “Kia” a “Maserati” and went on to describe its offerings in terms of its so-called Maserati. Such a description would make no sense in the wider world of automobile manufacture. Calling a “Kia” a “Maserati” while “in the context of GM” is symptomatic of the Humpty-Dumpty rationale:

“When I use a word,” Humpty Dumpty said, in a rather scornful tone, “it means just what I choose it to mean — neither more nor less.” “The question is,” said Alice, “whether you can make words mean so many different things.” “The question is,” said Humpty Dumpty, “which is to be master — that’s all.”

Claiming your own special context adds a layer of unnecessary obfuscation and cognitive friction. It removes clarity in naming.

Summary

In summary, I opine that these are the guidelines we need to keep in mind when picking names:

  • We are writing software instructions, not prose or poetry.

  • Pick from existing names that provide clarity within the appropriate context.

  • The order of priority for the appropriate context is: programming language, software patterns, domain terms, and finally everyday speech.

  • When using a pattern name, find the best match, not one that is merely close-enough.

  • Avoid claiming a special context for names so that you can make them mean what you want, instead of what they mean within a more widely shared context.


UPDATE: Some commenters from the Laravel community are being, shall we say, uncivil in their statements. Comments that are not civil, polite, respectful, and on-topic will be deleted out of hand. I reserve the right to further police comments as I see fit.

Submit To The Central Scrutinizer

(N.b.: I was unable to write this post without saying “ssscrrrrutinizer” out loud over and over. I blame my friend Ray Chavarie for inflicting Frank Zappa on me at an impressionable time in my life.)

After finishing Uncle Bob’s excellent Clean Code recently, I have been looking at my own code in Aura v2 even more critically. I started trying to apply more of the Clean Code principles to the different libraries, and thought I had done pretty well. But then I saw a scrutinizer.yml file in Luis Cordova’s Gush project, and I was curious about it.

I visited scrutinizer-ci.com to read up on the project, and man was I floored. Here is a service that will analyze your project on Github and assign it a quality grade that aligns really well with the Clean Code principles (among others). After you register a repository with Scrutinizer and perform the first analysis, you can fine-tune the process with a config file so that the Scrutinizer looks in the right directories for source code, gives you code coverage analysis, and so on.

For one of my first experiments with the Scrutinizer, I started with the Aura.Sql_Schema v2 package. I thought it would come out pretty well, but even after pointing the Scrutinizer in the right direction, it only scored an 8.61 or so. I guess that’s OK — but could we do better?

Using the Hot Spots page I was able to find the worst offenders in the classes and methods. Because we have 100% test coverage on all Aura code, it was a only matter of applying appropriate refactorings — the tests help to assure that changes don’t break anything. (The Scrutinizer will even suggest refactorings for you to apply.)

After the refactoring processes, the Scrutinizer reported a 9.46. You can see the Scrutinizer report for Aura.Sql_Schema here. There’s still room for improvement, but at least I know where the greatest improvement opportunities are.

Now that I’ve got a few days’ experience with Scrutinizer, I find it a very valuable tool. It’s very helpful as an objective assesment of code quality, so much so that I have added Scrutinizer badges to each Aura v2 package readme. You can see all the badges for all the packages on the v2 packages page.

Maybe the rest of the world knew about Scrutinizer before this, and I’m late to the game. I had not heard about it until recently, and now that I’m aware of it, I think it’s a great service for any developer concerned about code quality. Congratulations to @schmittjoh and everyone else involved in Scrutinizer. Very nicely done!

UPDATE: In response to a question elsewhere: yes, Scrutinizer is free for open-source projects.

First Aura v2 Beta Releases of Web_Project, Cli_Project, and Framework_Project

Earlier this week, we put the final touches on the “micro/macro” frameworks for v2 web projects and v2 command line projects. Although these had been delayed a bit while working out the Aura.Di v2 beta release, they both now have their first “Google beta” releases!

… The idea is that [Aura.Web_Project] starts as a very minimal system, with only router, dispatcher, request, and response functionality. But thanks to the Composer-assisted configuration system, it’s very easy to add whatever functionality you want, making the project as large or as small as you need. …

Aura.Cli_Project takes exactly the same approach, but for command-line applications. It consists of a “context” and standard I/O system (the equivalents of a request and response), along with a console and dispatcher. It uses the same configuration system as Web_Project, so you start with a very minimal system that grows only as you need it.

Each project is little more than a skeleton around a core “kernel” package. The Aura.Web_Kernel is what actually provides the glue to connect the underlying library packages together, as does the Aura.Cli_Kernel.

Keeping the kernel separate from the project means we can update the kernel without having to re-install a project.

via First v2 Beta Releases of Web_Project, Cli_Project, and Framework_Project.

How To Modernize Your Legacy PHP Application

It is accomplished: “Modernizing Legacy Applications in PHP”, the book that will help you modernize your legacy PHP codebase, is complete. You can get it now it at https://leanpub.com/mlaphp.


Is your legacy PHP application composed of page scripts placed directly in the document root of the web server? Do your page scripts, along with any other classes and functions, combine the concerns of model, view, and controller into the same scope? Is the majority of the logical flow incorporated as include files and global functions rather than class methods?

If so, you already know that the wide use of global variables means that making a change in one place leads to unexpected consequences somewhere else. These and other factors make it overly difficult and expensive for you to add features and fix bugs. Working with your legacy application feels like dragging your feet through mud.

But it doesn’t have to be that way! Modernizing Legacy Applications in PHP will show you how to modernize your application by extracting and replacing its legacy artifacts. We will use a step-by-step approach, moving slowly and methodically, to improve your application from the ground up.

Moreover, we will keep your application running the whole time. Each completed step in the process will keep your codebase fully operational with higher quality. When we are done, you will be able to breeze through your code like the wind. Your code will be autoloaded, dependency-injected, unit-tested, layer-separated, and front-controlled.


From the Foreword by Adam Culp:

Developing with PHP has really matured in recent years, but it’s no secret that PHP’s low level of entry for beginners helped create some nasty codebases. Companies who built applications in the dark times simply can’t afford to put things on hold and rebuild a legacy application, especially with today’s fast paced economy and higher developer salaries. To stay competitive, companies must continually push developers for new features and to increase application stability. This creates a hostile environment for developers working with a poorly written legacy application. Modernizing a legacy application is a necessity, and must happen. Yet knowing how to create clean code and comprehending how to modernize a legacy application are two entirely different things.

But understanding how to use these refactoring processes on a legacy codebase is not straight forward, and sometimes impossible. The book you’re about to read bridges the gap, allowing developers to modernize a codebase so refactoring can be applied for continued enhancement.


Early reviews and testimonials from the feedback page:

  • “This is one of those books that PHP developers from all skill levels will be able to glean value from, and I know after just a single read-through that it will be an oft-referenced resource when I need to convert my old legacy-based procedural code into something cleaner, object-oriented, and testable.” (J. Michael Ward)

  • “As I followed the exercises in the book, my questions almost seemed to be anticipated and answered before the chapter was over. Structurally the book is very well paced. Chapters that I breezed over tended to be more useful than I thought they would be. I’ve been testing for years and I still picked up some useful tidbits about structuring my tests. Just having the step-by-step advice of an expert really made a difference.” (James Fuller)

  • “Reading through the book, it feels like you’re pair programming with the author. I’m at the keyboard, driving, and the author is navigating, telling me where to go and what to do next. Each step is practical, self-contained and moves you closer to the end goal you seek: maintainable code.” (Joel Clermont)

  • “This book helped me slay a 300k line of code giant and has allowed me to break out my shell. The refactored code has 15% code coverage for unit testing which grows every day.” (Chris Smith)


If you feel overwhelmed by a legacy application, “Modernizing Legacy Applications in PHP” is the book for you. Purchase it today and get started making your own life easier!

Composer-Assisted Two-Stage Configuration in Aura

After a long period of consideration, research, and experiment, we have found a non-static solution for programmatic configuration through a DI container. It is part of a two-stage configuration process, implemented through a ContainerBuilder.

The two stages are “define” and “modify”:

  • In the “define” stage, the Config object defines constructor params, setter method values, and services. This is the equivalent of the previous single-stage Solar and Aura v1 configuration system.

  • The ContainerBuilder then locks the Container so that its definitions cannot be changed, and then begins the “modify” stage. In this second stage, we retrieve service objects from the Container and modify them programmatically.

So now, instead of each Aura package carrying a pair of define and modify includes in a subdirectory named for the config mode, we have a single class file for each config mode. The class file is in a subnamespace _Config under the package namespace. Here are two examples, one from the Aura.Web_Kernel package, and one from the Aura.Web_Project package.

Because they are classes, you can call other methods as needed, subclass or inherit, use traits, create instance properties and local variables for configuration logic, and so on. You could even call include in the methods if you wanted, keeping the class as a scaffold for much larger configuration files. This gives great flexibility to the confguration system.

To make sure the Aura project installation can find all the package config files, we use the {"extra": {"aura": { ... } } } elements of the composer.json in each package to provide a mapping from the config mode to the config class.

Read the whole article at Composer-Assisted Two-Stage Configuration.