Below you will find pages that utilize the taxonomy term “OOP”
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:
Where do types come from?
In essence, everything is a string.
Well, you can always go one layer deeper and find out what a string really is, but for web apps I work on, both input data and output data are strings. The input is an HTTP request, which is a plain-text message that gets passed to the web server, the PHP server, the framework, and finally a user-land controller. The output is an HTTP response, which is also a plain-text message that gets passed to the client. If my app needs the database to load or store some data, that data too is in its initial form a string. It needs to be deserialized into objects to do something and later be serialized into strings so we can store the results.
Negative architecture, and assumptions about code
In “Negative Architecture”, Michael Feathers speaks about certain aspects of software architecture leading to some kind of negative architecture. Feathers mentions the IO Monad from Haskell (functional programming) as an example, but there are parallel examples in object-oriented programming. For example, by using layers and the dependency inversion principle you can “guarantee” that a certain class, in a certain layer (e.g. domain, application) won’t do any IO - no talking to a database, no HTTP requests to some remote service, etc.
Objects should be constructed in one go
Consider the following rule:
When you create an object, it should be complete, consistent and valid in one go.
It is derived from the more general principle that it should not be possible for an object to exist in an inconsistent state. I think this is a very important rule, one that will gradually lead everyone from the swamps of those dreaded “anemic” domain models. However, the question still remains: what does all of this mean?