On Github Ocramius / zf2-best-practices
We have enough talks like that
I don't want to be too negative
How exciting!
Yes, this happens every few years!
Sometimes it's even innovative stuff!
(was that sarcasm?)
Did you talk to the business folks?
Did you talk to your team?
Did you look at existing solutions?
You did, right?
(was that sarcasm?)
Because everything needs an API, right?
(was that sarcasm?)
Yes, that's the real API First
This means that you need to do actual brainwork!
It's also the most fun part!
We want to do TDD
(Tears driven development)
That's what you want to expose via HTTP!
Webpage?
REST API?
...your project.
Do you really need API first?
No frontend
No forms
No UX
Async is ok
If you don't mix it with an API
Or you make a SPA
Only after the domain stuff!
As usual, Skeleton Application
Please use composer, don't make lives difficult
Clean it up!
Remove init_autoloader.php
Remove the Application module routes
Remove the public/ styles
Keep it minimal first
Like the Application module error template
Use composer for autoloading
No weird paths like ModuleName/Module.php
PSR-0 or PSR-4 structure
Part of the application repository
This is not thought-work
This is integration work
This is not thought-work
This is integration work
Only few interfaces implemented:
Everything more is a smell
Write a test: unserialize(serialize($module->getConfig())) == $module->getConfig()
References to class/interface name must use ::class
Service names should use ::class
No magic key constants, use Module class constants
reuse
disabling/enabling
infrastructure
Domain
Namespacing
For every used class / function / constant you need the right composer.json entry!
Don't design a Controller without a Business Interaction first!
(This means that your domain must expose something about the interaction)
You can use Commands
You can use Value Objects from the Domain
Probably only for GET
Business interactions != CRUD
RPC is perfectly OK
Form's can't really be avoided
Sometimes we can just use an InputFilter
Build the interactions first, the form fancyness later on.
Avoid form binding
$form->bindValues($presets) is perfectly OK
$form->getData() and MyCommand::fromFormData($data) is simpler!
MASSIVE simplification!
I don't really have anything to say here
It is specific to the domain
I suggest leveraging an existing repository implementation
Refactor a bit every day
Keep it extremely clean/SOLID
No shortcuts
(once you know how to do it)
Factories all the way
Reduced Configs (prefer factories)
Small Methods
SRP
You can do it with eyes closed
And with one hand.
No real amount of thought-work
Just time consuming
You can think about other stuff meanwhile!
You can replace any code, any time
Less bugs, or easier to tackle
Manageable technical debt
Increased code understanding
class MyService implements ServiceLocatorAwareInterface { ... }
Design in 1 hour
Code in 15 minutes
Test in 10 minutes
Addition of ~120 minutes of technical debt
class MyService { ... }
Design in 1 hour
Code in 15 minutes
Code factory in 5 minutes
Test in 10 minutes
Test factory in 10 minutes
Addition of ~30 minutes of technical debt
With ServiceLocatorAwareInterface: ~200 minutes of work
Without ServiceLocatorAwareInterface: ~130 minutes of work