Posts

Showing posts with the label design patterns

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...

The Value of "Value Objects"

Herberto Graça recently wrote a great summary on Value Objects , and I commented on it on Reddit , saying: ...something that could flesh out the case for value objects [is] the fact that it allows you to model complex rule interactions by representing the concepts of the core domain and letting them interact as they would in said setting . This results in code that reads very much like "business-speak", making it easier to translate back and forth from the stakeholders to the developers. The comment has its own illustration of the idea, but I wanted to expand on the utility of value objects in a bit more depth in this blog post. If you need a primer on what value objects are in the first place, Graça's article is a great start. A lightning-fast DDD reminder Within Domain Driven Design , we separate our code into at least two distinct models: The Application Model , which crystalises the top-level use-cases (or commands ) of the system (e.g. ApplyForFinancialLoa...

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...

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, ...