The document discusses change and how it begins with awareness. It talks about using testing to improve code and catch defects early. It describes using a service container and dependency injection to allow flexible configuration and extension of classes. It then discusses creating a custom user manager and discriminator to allow a FOSUserBundle to support multiple user classes. Finally, it proposes a bundle called NmnMultiUserBundle to implement this solution and mentions some books related to testing and code quality.
1. Change begins with awareness
Appetite comes with testing
“It's a dangerous business, Frodo, going out
your door. You step onto the road, and if you
don't keep your feet, there's no knowing
where you might be swept off to.”
J.R.R. Tolkien, The Lord of the Rings
10. Change begins with awareness
And...
“Supporting multiple user classes is not easy at all. It would
make the bundle code far more complex as we would
basically need to change all places interacting with the user
to be able to handle all user classes. I don't really want to
go this way (it will also make it more likely to introduce
bugs).”
...a delusion
11. Change begins with awareness
But...
In Symfony2, all core classes use the service container,
so it is easy to extend, configure and use any object
...a hope
12. Change begins with awareness
Service Container
Dependency Injection Container
use AcmeHelloBundleMailer;
$mailer = new Mailer('sendmail');
$mailer->send('info@netmeans.net', ... );
13. Change begins with awareness
Service Container
Dependency Injection Container
class Mailer
{
private $mailerType;
public function __construct($mailerType)
{
$this->mailerType = $mailerType
}
public function send($to, ...)
{
...
}
}
services:
my_mailer:
class: AcmeHelloBundleMailer
arguments: [sendmail]
14. Change begins with awareness
Service Container
Dependency Injection Container
class HelloController extends Controller
{
public function sendEmailAction()
{
$mailer = $this->get('my_mailer');
$mailer->send('info@netmeans.net', ... );
}
}
15. Change begins with awareness
FOSUserBundle
fos_user:
db_driver: orm
firewall_name: main
user_class: AcmeUserBundleEntityUser
16. Change begins with awareness
FOSUserBundle
fos_user:
db_driver: orm
firewall_name: main
user_class: AcmeUserBundleEntityUser
service:
user_manager: custom_user_manager
17. Change begins with awareness
So ...
...a solution
We have to create our custom
UserManager that accepts in the
constructor an object that have the
responsibility to discriminate user
types
18. Change begins with awareness
First of all: test
We start writing some functional
tests to check correct integration
of FOSUserBundle
19. Change begins with awareness
Custom UserManager
Class UserManager extends FOSUserBundleEntityUserManager
{
protected $userDiscriminator;
public function __construct(..., UserDiscriminator $userDiscriminator)
public function getClass()
{
return $this->userDiscriminator->getClass();
}
}
20. Change begins with awareness
UserDiscriminator
public function getClass()
{
return 'Acme/UserBundle/Entity/UserOne';
}
21. Change begins with awareness
From here it's all smooth
With little iterations, we improve
UserManager and UserDiscriminator
with unit and functional tests,
passing from a dirty code to a more
elegant one
24. Change begins with awareness
NmnMultiUserBundle
Ok, it is an hack :)
A lazy way to use for free most of the
functionality of FOSUserBundle ...
... but it is ready to be improved by
anyone.
26. Change begins with awareness
Some Books
I know this sounds strident and unilateral, but given the record I don't
think the surgeons should have to defend hand-washing, and I don't
think programmers should have to defend TDD
The Clean Coder
A code of Conduct for Professional Programmers
Martin, Robert C.
27. Some Books
In software development, “perfect” is a verb, not an adjective
Extreme Programming Explained
Embrace Change
Beck, Kent
Change begins with awareness
In XP, testing is as important as programming
28. Change begins with awareness
Some Books
Building testable applications is Hard
The Grumpy Programmer's Guide To Building
Testable Applications in PHP
Hartjes, Chris
The reason for investing in automated testing is obvious: any bugs you
catch before your application makes it into production cost less in terms
of resources (money, developer time) to fix than fixing it into production