Posts

Improve your local web app development with Docker

Have you ever had a situation where there was a bug in some deployed application, but the simple act of running that application locally made the bug impossible to find? It could've been that there was no local infrastructure (e.g. databases) to back the running services. Or port-configuration was hard-coded into the application (so it collided with other ports on your host machine; people love to hard-code to port 8000 , 80 or 8080 ). Or, scarier still, the application was never actually run locally because it was deemed too difficult in the first place (in which case, you wonder how the deployed application worked at all)? In an age where we have Docker to effectively ship the containerized machines that our applications run on, there really isn't an excuse for making local development a more consistent experience. If there is greater confidence in running code locally, it becomes quicker to spot and fix bugs. It becomes quicker to onboard new developers and make them pr...

Why I love the repository pattern

Persisting application state is not an easy job , to say the very least. We have an entire cottage industry of vendors who promise to simplify these issues for us. But there is a long-existing design pattern that which provides a logical separation in your application to help tackle this problem, without needing to commit to a specific database technology or library. The repository pattern aims to isolate the complexities concerning the persistence of data (complexities which are often vendor specific) from the the business-logic of your application. In your app, you will usually: 🔍 Find some specific entity in question 🛠️ Perform some operation on that entity, obeying a set of rules to ensure that it doesn't enter an invalid state 💾 Persist that entity Steps (1) and (3) both concern communication with the storage layer (e.g. the database) that you are using. It will involve mapping the data to/from storage and into objects/data structures that your app understa...

Don't call your interfaces interfaces

Image
An old, prolific convention of software development has been to prefix or suffix interfaces with something that specifically designates them as such. So if I have an interface for a clock, rather than calling it Clock , many would call it IClock or ClockInterface . In PHP, the convention is so ingrained that our core inter-framework operable PSR standards adopt this. I am going to spend this article arguing against this convention. If you need -Interface , you probably have your abstractions wrong Typically, then someone uses Interface as a suffix, it is because they have a concrete implementation of the class without the suffix (which is in some sense the "real", canonical, implementation) and they're trying to stub the concrete functionality out when it comes to testing. So to give an example, you might have Http\ClientInterface and some concrete implementations Http\Client (in production) and Http\TestClient (for writing unit tests). namespace Http ; inte...

Code Smells: Static References to Time

So you need to do some time-specific calculations in your application. It’s related to the current time, so you do the usual thing, and new up a DateTime object: $now = new DateTime() ; Seems innocuous, right? But you quickly run into some pretty nasty problems: Your code is now very difficult to test reliably . To make any assertions on the behaviour that aren't time-flakey (i.e. they work today but not in a few months time), you’ll now need to do something with the internal system clock while the test is running. Perhaps you can get away with running your tests in a container whose clock is fixed to the desired time, but this is a considerable amount of work to get around the brittleness of the code itself (we will see below how to achieve this same outcome without the need for such machinery) . If something is "off" with the internal system clock (e.g. the timezone isn't the one you'd expected) and you need to make a change to your application code, ...