Our highlights from PHPBenelux 2019
About 2 weeks ago our team of back-end developers visited the tenth edition of PHPBenelux. After attending quite a few talks over the 1,5-day conference we’ve highlighted three of them that we found most interesting. First, Kevin will tell you about Frank de Jonge’s talk concerning event sourcing. Vincent will highlight the talk about Symfony’s new messenger component by Tobias Nyholm. Last, I’ll share some key points made by Ike Devolder in his talk about defensive programming.
A practical introduction to event sourcing by Frank de Jonge
Having read the book Domain-Driven Design in PHP, I already had a good understanding of what event sourcing is so the talk was easy to follow. I do recommend the book and recommend you stalk Frank de Jonge to know when and where he’s speaking next, but also because he’s a very interesting person to follow!
One of the things that made me reluctant to use event sourcing was that simple tasks would require a tedious amount of work and development would become much slower. However, Frank addressed that and claims that even though simple tasks take longer, complex tasks are easier.
Another point is that testing, more specific with “Eventsauce”, appears to be a lot simpler than I originally thought by following a Given, When, Then kind of structure, check the slide for an example.
The talk certainly inspired me to get some event sourcing going on, I can’t wait to use it in a project that could benefit from it and will consider his library “Eventsauce” when I do. Before that day arrives, I’ll probably be using it in one of my side projects already!
Queues, busses and the messenger component by Tobias Nyholm
This very inspiring talk given by Tobias was a short intro on how the new Symfony message component works and some use cases on how to implement it.
First off he started by giving some examples of code he used to write a few years back and started improving it and optimizing the code for the message component.
I was impressed by how fast you can get this component working and the flexibility it provides for your application. The core concept is that you serialize a message (simple PHP object) and pass it to the message bus. This bus can be configured in a multitude of ways to decide how to pass that message to handlers. This JSON message doesn't need to stay inside the boundaries of your app but can be pushed on an external queue like Kafka or RabbitMQ, making it a communication channel between one or more apps.
To round things up I would recommend checking out the component yourself to see what it is all about.
Defensive PHP Programming by Ike DevolderEven though the level of this talk may have been more suitable for beginners, there were some good reminders for more experienced developers and definitely a lot of solid advice for junior developers. Here’s a short summary of some of the key points made by Ike.
Avoid elseAt yappa, we’ve incorporated this into the training of new developers as an unofficial “rule”. Most of the time it’s possible to avoid having to write an else-clause for every if-clause you write. This will keep the code executed in a certain condition closer to that condition and will prevent having many levels of nested indentations in your function.
No abbreviationThis one’s simple but sometimes forgotten: don’t use abbreviations.
Limit instance variablesSure, a larger object like a Customer class might have many properties. But should all of those be defined on the Customer class itself? Probably not. You’ll want to prevent your class becoming a huge pile of parameters that are set through the constructor or even more methods. You can improve that class by grouping multiple properties into another class that makes sense. A customer doesn’t have a shipping street, shipping number, etc., a customer has a shipping address and an invoice address, both are of the type address, that in turn consists of things like the street and city.
Fail early and avoid deep nestingAnother that we pretty much consider a “rule” here. Please don’t nest an if-clause in another and another, etc. Try and fail (or return) early. Note the example. No input to process? Stop and return. No characters to remove? Stop and return. This will make your method much easier to understand and will prevent you from having many levels of indentation.
Avoid optional dependencies
Sometimes a dependency is seen as optional. It’s injected through the constructor, but nullable, or maybe even through a setter. The most common example is a logger. Let’s say I want to log some debug information from my class but the logger is defined as an optional dependency. I can’t simply log a line because that will make my code fail when the logger isn’t present. So I’ll have to check whether the logger is present before calling a method on it, every single time. This will clutter your class with many if-clauses, and even worse, my class shouldn’t even decide whether to log or not, that should probably be decided elsewhere.
So how can we solve this problem? First of all, we need to make sure we always inject a logger through the constructor so we can get rid of all the checks. But what if I don’t want to save that logging output in certain situations? If we define an interface for a logger we can simply inject a logger that does nothing in those situations (but does comply with the interface) and use the normal logger in every other situation.