Simple Solutions 1 - Active Record versus Data Mapper
Having discussed different aspects of simplicity in programming solutions, let’s start with the first topic that should be scrutinized regarding their simplicity: persisting model objects. As you may know, we have competing solutions which fall into two categories: they will follow either the Active Record (AR) or the Data Mapper pattern (DM) (as described in Martin Fowler’s “Patterns of Enterprise Application Architecture”, abbrev. PoEAA).
Active record
How do we recognize the AR pattern? It’s when you instantiate a model object and then call save()
on it:
What's a simple solution?
“As I’m becoming a more experienced programmer, I tend to prefer simple solutions.” Or something similar. As is the case with many programming-related quotes, this is somewhat of a blanket statement because who doesn’t prefer simple solutions? To make it a powerful statement again, you’d have to explain what a simple solution is, and how you distinguish it from not-so-simple solutions. So the million-dollar question is “What is a simple solution?”, and I’ll answer it now.
My book-writing workflow
By request: what’s my workflow for writing books? Steps, tools, etc.
Writing with the Leanpub platform
A long time ago I noticed that testing-advocate Chris Hartjes published his books on Leanpub. When I had the idea of writing a book about the Symfony framework, I tried this platform and it was a good match. You can write your book in Markdown, commit the manuscript to a GitHub repository, and push the button to publish a new version. Leanpub will generate EPUB and PDF versions for you. Readers can be updated about releases via email or a notification on the website.
When to use a trait?
When to use a trait? Never.
Well, a trait could be considered to have a few benefits:
Benefits
- If you want to reuse some code between multiple classes, using a trait is an alternative for extending the class. In that case the trait may be the better option because it doesn’t become part of the type hierarchy, i.e. a class that uses a trait isn’t “an instance of that trait”.
- A trait can save you some manual copy/paste-ing by offering compile-time copy/paste-ing instead.
Downsides
On the other hand, there are several problems with traits. For instance:
Decoupling your security user from your user model
This article shows an example of framework decoupling. You’ll find a more elaborate discussion in my latest book, Recipes for Decoupling.
Why would it be nice to decouple your user model from the framework’s security user or authentication model?
Reason 1: Hexagonal architecture
I like to use hexagonal architecture in my applications, which means among other things that the entities from my domain model stay behind a port. They are never exposed to, for instance, a controller, or a template. Whenever I want to show anything to the user, I create a dedicated view model for it.
Effective immutability with PHPStan
This article is about a topic that didn’t make the cut for my latest book, Recipes for Decoupling. It still contains some useful ideas I think, so here it is anyway!
DateTimeImmutable is mutable
I don’t know where I first heard it, but PHP’s DateTimeImmutable
is not immutable:
<?php
$dt = new DateTimeImmutable('now');
echo $dt->getTimestamp() . "\n";
$dt->__construct('tomorrow');
echo $dt->getTimestamp() . "\n";
The result:
1656927919
1656972000
Indeed, DateTimeImmutable
is not really immutable because its internal state can be modified after instantiation. After calling __construct()
again, any existing object reference will have the modified state as well. But an even bigger surprise might be that if a constructor is public
, it’s just another method that you can call. You’re not supposed to, but you can. Which is another reason to make the constructor of non-service objects private
and add a public static constructor to a class that you want to be immutable:
New book: Recipes for Decoupling
My new book Recipes for Decoupling is 100% complete and available now!
And now some other news related to this book.
A little background information
My new book is based on two things: 20 years of experience with (mostly framework) coupling issues in legacy code, and the hypothesis that PHPStan, the automated static analysis tool for PHP, can help us keep our code decoupled. Decoupling often means we want to use a dependency, but don’t want to couple our code too tightly to it. The process of decoupling often involves some kind of rule, like “don’t use Container::get()”, but we don’t want to focus on this rule all the time, or explain it to new members of the team. Instead, we want a tool that shows you an error when you don’t follow the rule. Such an error will break the build of the project and prevent you from ever coupling to a dependency in this specific way again.
DDD entities and ORM entities
I was tweeting something about having separate “DDD” and “ORM” entities in a project in a project, and that I don’t understand this. There were some great comments and questions, thanks a lot for that! To be honest, I understand more about it now. In this article I’ll try to provide some more information about this.
I’m glad many developers want to use input from the book “Domain-Driven Design” by Eric Evans to improve their domain model. I recommend reading this book and getting your information from the source, because unfortunately the internet, tweets, e-books, including my own books, aren’t able to reflect a full, nor a correct view of everything there is to find out about this topic. All too often DDD is completely misinterpreted to be “an elitist, dogmatic approach to programming, where we use DTOs, layers, and CQRS”…
Too much magic?
Years ago my co-worker Maurits introduced me to the term “magic” in programming. He also provided the valuable dichotomy of convention and configuration (or in fact, he’d choose configuration over convention…). I think this distinction could be very helpful in psychological research, figuring out why some people prefer framework X over framework Y. One requires the developer to spell out everything they want in elaborate configuration files, the other relies on convention: placing certain files with certain names and certain methods in certain places will make everything work “magically”.
Millennials doing things everyone should know about
Last year I had a video call with Tomas Votruba, creator of Rector, who kindly took the time to explain a lot of things about this project. We finished the call and I couldn’t wait to tell my partner how nice it was. I said to her: we should have recorded it, I’m sure it would be useful for other people too. She replied: this is so typical; millennials having a nice conversation and then they want to let the world know about it.