Alias as a Code Smell
This post was updated in August 2020 with fresh know-how.
What is new?
Updated with PHPStan rules available in Symplify 8.
Do you have 2 class with the same name? App\Entity\Product and App\Entity\Product? Of course not. But I bet you have at least 2 classes with the same short name *\Product and *\Product.
And that smells... Why?
In recent projects, I consult I start to notice an interesting pattern. It's how important are uniquely named short classes. Short class name = the part after last \.
How would you like to use this code?
Duplicated Short Classes sponsored by DDD
When I ask why the programmer picked such a naming, more often than not they refer DDD patterns, where you don't care if the element is interface, trait or abstract. The naming is always the same. Do you know which of them is class, interface, category Query and product Query?
QueryQueryQueryQuery
Now the programmer has to become a detective.
Query→ see the namespace, oh it's a/Contract, that's probably an interfaceQuery→ oh, the namespace is/Behavior, that's probably a traitQuery→ see the file location, it's in/Model/Category, that's probably a category queryQuery→ see the file location, it's in/Model/Product/Contract, that's probably a product query interface
Good job! The code starts to steal time and energy the reader 🤦.
Make it Clear with Aliases?
Luckily, there is a band-aid to this problem, aliases!
<?php
namespace App;
use App\Behavior\Query as QueryTrait;
use App\Model\Category\Query as CategoryQuery;
use App\Model\Product\Contract\Query as ProductQueryInterface;
use App\Contract\Query as QueryInterface;
final class ProductQuery implements ProductQueryInterface, QueryInterface
{
use QueryTrait;
public function findByCategoryQuery(CategoryQuery $categoryQuery)
{
// ...
}
}
Now we have 200 % more code and but it's a bit more clear.
When you see an alias, and it's not for 3rd party code,
you have a code smell in there.
Get rid of it!
Use Your Common Sense
If you see a car of Tesla, you'd probably name it "Tesla car". Not a "car".
Get rid of aliases and name your classes in a unique and clear way:
<?php
namespace App;
use App\Behavior\QueryTrait;
use App\Model\Category\CategoryQuery;
use App\Model\Product\Contract\ProductQueryInterface;
use App\Contract\QueryInterface;
final class ProductQuery implements ProductQueryInterface, QueryInterface
{
use QueryTrait;
public function findByCategoryQuery(CategoryQuery $categoryQuery)
{
// ...
}
}
Automated Smell Detection
Do you need to help to find these smells? Just add NoDuplicatedShortClassNameRule to your coding standard:
# phpstan.neon
rules:
- Symplify\CodingStandard\Rules\NoDuplicatedShortClassNameRule
Happy coding!