OpenBuildings/cherry — pull request #5 by hkdobrev (2014-01-22 09:16:27+00:00)
Title: Use multiple namespaces

Each part of the source code and the tests is using a separate namespace.
This way a class could access any of the classes in its namespace, but
should explicitly "require" (with `use`) the classes from the other parts
of the project. This is a basic implementation of dependency injection (DI)
using PHP namespaces.

A good example of such workflow is the Composer library and also many of the
packages in the Symfony ecosystem.

Pros:

- Simpler class names. There are no underscores in the class names. They are
ara changed to use correct English order of the words (`SelectCompiler` instead
of `Compiler_Select`). But this is entirely optional. The name of file exactly
represents the name of the class. In the previous case when you see a folder you
don't know if it is for a namespace of a class prefix.
- The DI mentioned above.
- Explicitly requiring classes would easily show you
which class requires a lot of others and which is self-contained.
You see code for refactoring more easily.
- The tests are in namespaces too. You can easily see the test classes are only dependent
on the test case class and the classes being tested. They do not depend on each other.
- There is no need for a custom autoloader in the tests bootstrap. All we do is just add
an additional namespace to the existing autoloader which works with namespaces. This
is similar to the way the Composer library loads its test files.

Cons:

- When using the library in external code (application project or another library) you
need to require (use) every class from the Cherry library you are using in a file.
The difference compared to before is that you need to use different namespaces for the
different types of classes It increases the typing of the use clauses a bit.
This is again something which is extremely common in the Symfony/Composer ecosystem.
- You cannot use `__NAMESPACE__` from one part of the project to reference a class from another.
For example in `Openbuildings\Cherry\SQL\SQL` using `__NAMESPACE__.'\SelectQuery` would
result in `Openbuildings\Cherry\SQL\SelectQuery` which does not exist.
PHP 5.5 offers a nice solution with the `::class` static property.
When you have used `SelectQuery` like so:

use Openbuildings\Cherry\Query\SelectQuery;

You could then write `SelectQuery::class` whic would result in `Openbuildings\Cherry\Query\SelectQuery`.