Rob Allen has been programming with PHP since 1999 and is a member of the PHP community. He is the lead author of Zend Framework in Action and is a contributor to Zend Framework, developing the Zend_Config component. Rob holds a Masters degree in Electronic Engineering from the University of Birmingham in the UK and is the Technical Director of Big Room Internet in the UK, focussing on project management and the company’s future technologies. Rob is a DZone MVB and is not an employee of DZone and has posted 34 posts at DZone. You can read more from them at their website. View Full User Profile

Use Statements and Code Readability

03.17.2014
| 6057 views |
  • submit to reddit

I was having a discussion on IRC about use statements and whether they improved code readability or not.

The choices

Consider this hypothetical code:

$cache = new \User\Service\Cache();
$mapper = new \User\Mapper\User($cache)
$form = new \User\Form\Registration($mapper);
$form->process($request->getPost());

vs

use User\Service\Cache;
use User\Mapper\User;
use User\Form\Registration;

// other code

$cache = new Cache();
$db = new User($cache)
$form = new Registration($mapper);
$form->process($request->getPost());

The first snippet is completely unambiguous at the expense of verbosity. Those longer class names make it a little hard to quickly parse what it going on. The second is clearly less cluttered, but is at the expense of ambiguity. Exactly what class is User? I would have to go to the top of the file to find out. Should I use aliases? If so, how should I name them?

This is even more interesting in the context of pull requests where the use statement is already in place in the file. As a result the diff you are reviewing doesn’t have the use statement in it, so you have to go a different view to check that the class in use is actually the correct one. If fully qualified class names are used, then the PR’s diff is self-contained and easier to review.

Getting advice

As with a lot of things in programming, there are pros and cons, so I reached out to the people who follow me on Twitter and asked them:

Do people like “use” statements or is the separation of 100s of lines of code between the real class name and it’s actual use a nuisance?

— Rob Allen (@akrabat) March 15, 2014

There were a number of interesting responses, including:

@akrabat I think use statements just abstract where the class is coming from. Some people find that useful. Helps keep lines under 80 chars

— Herman Radtke (@hermanradtke) March 15, 2014

@akrabat I think it's helpful seeing all of the packages used by a class without having to look through the full code.

— Ben Johnson (@ben_johnson) March 15, 2014

@akrabat One reason I like them is that I can glance at a file and know dependencies immediately.

— weierophinney (@mwop) March 16, 2014

There seemed to be consensus around the use of use statements. The main reasons appeared to be the ability to see the class dependencies at the top of the file and improved code readability (less clutter).

Some people also pointed out that you can introduce clarity when importing:

@akrabat I do appreciate what you are saying about the indirection use statements introduce. Aliasing unclear class names can help.

— Richard Miller (@mr_r_miller) March 15, 2014

@akrabat Ambiguity can be solved using aliases. For example: use My\Mapper\User; vs use My\Mapper\User as UserMapper;

— Nikola Poša (@nikolaposa) March 16, 2014

@akrabat I always import the namespace below the class. So my hints are somespace\user

— Brandon Savage (@brandonsavage) March 15, 2014

If you consistently name your aliases, then the code is shorter and also just as clear. If we take Brandon’s approach, then the example above becomes:

use User\Service;
use User\Mapper;
use User\Form;

// other code

$cache = new Service\Cache();
$db = new Mapper\User($cache)
$form = new Form\Registration($mapper);
$form->process($request->getPost());

Now the “aliases” are codified by the PHP namespace name and so you aren’t at the mercy of the developer who names the alias. However, the list of use statements is no longer a list of dependent classes, it’s a list of dependent namespaces.

My thoughts

Having thought about all the responses I received and having slept on it, I think that it’s preferable to be able to organise your code and name your classes such that when importing we minimise ambiguity. If we reorganised, we could come up with something like this:

use User\UserCache;
use User\UserMapper;
use User\RegistrationForm;

// other code

$cache = new UserCache();
$db = new UserMapper($cache)
$form = new RegistrationForm($mapper);
$form->process($request->getPost());

We have now flattened our class hierarchy which has resulted in clearer class names. Of course, this is not always possible and in those cases, I think that consistent naming of aliases is the way to go.

Have I missed something obvious? How do you import classes?

Published at DZone with permission of Rob Allen, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Erin Garlock replied on Mon, 2014/03/17 - 1:08pm

use User\Service\Cache;
use User\Mapper\User;
use User\Form\Registration;

vs.

use User\Cache;
use User\User;
use User\Registration;


So this is really about naming your packages correctly. My experience has been the natural inclination is to group by type of functionality (e.g. Service, Mapper, Form) instead of just by service provided. In the first example, there usually is a proliferation of subpackages with only a couple classes each.

Oleksandr Alesinskyy replied on Wed, 2014/03/19 - 5:44am

I am wondering why this article is in the Java section?

Erin Garlock replied on Wed, 2014/03/19 - 8:45am


While the code snippet may not be Java, the same concept applies to Java package names.  It is a common audit finding that packages frequently have only one or two interfaces/classes (frequently Interface X, and Class Ximpl).  This kind of structure just makes things harder to find.

Oleksandr Alesinskyy replied on Wed, 2014/03/19 - 9:42am in response to: Erin Garlock

 That's true - but why not designate a cat as "cat" and not as a "small animal with four legs, claws, fur and a long tail"?

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.