Outside In Design

Following on from my previous post about not having too much configuration, I want to talk about how I design software. I try and follow what I call “outside in design”; I try and make something that requires the bare minimum amount of configuration to cover the most common of use-cases. Once this functionality is working, further configuration can be added to cover the next most common use cases. API Reduction As A Feature The first example I want to go through is how I removed options from an HTTP rate limiter we use....

December 12, 2024 · 8 min

The reports of UML's death are greatly exaggerated

This is in response to the recent posts about the death of UML; while I think some parts of UML have fallen ill, the remaining parts are still alive, and useful to this day. TLDR Out of 14 types of diagram there are 3 that I use on a regular basis: Activity Diagram, State Machine Diagram, and Sequence Diagram. I think the Timing Diagram is borderline, but I can only think of a couple of occasions when it has been useful....

September 11, 2022 · 4 min

Architecture Decision Records

This is a text version of a short talk (affectionately known as a “Coffee Bag”) I gave at work this week, on Architecture Design Records. You can see the slides here, but there isn’t a recording available, unfortunately. It should be noted; these are not to replace full architecture diagrams; you should definitely still write C4 Models to cover the overall architecture. ADRs are for the details, such as serializer formats, convention-over-configuration details, number precisions for timings, or which metrics library is used and why....

June 29, 2019 · 8 min

Microservices or Components

One of the reasons people list for using MicroServices is that it helps enforce separation of concerns. This is usually achieved by adding a network boundary between the services. While this is useful, it’s not without costs; namely that you’ve added a set of new failure modes: the network. We can achieve the same separation of concerns within the same codebase if we put our minds to it. In fact, this is what Simon Brown calls a Modular Monolith, and DHH calls the Majestic Monolith....

October 28, 2018 · 6 min

Tweaking Processes to Remove Errors

When we are developing (internal) Nuget packages at work, the process used is the following: Get latest of master New branch feature-SomethingDescriptive Implement feature Push to GitHub TeamCity builds Publish package to the nuget feed Pull request Merge to master Obviously 3 to 6 can repeat many times if something doesn’t work out quite right. There are a number of problems with this process: Pull-request after publishing Pull requests are a great tool which we use extensively, but in this case, they are being done too late....

December 9, 2017 · 3 min

Evolutionary Development

Having recently finished reading the Building Evolutionary Architectures: Support Constant Change book, I got to thinking about a system which was fairly representative of an architecture which was fine for it’s initial version, but it’s usage had outgrown the architecture. Example System: Document Storage The system in question was a file store for a multi user, internal, desktop based CRM system. The number of users was very small, and the first implementation was just a network file share....

November 17, 2017 · 4 min

Strong Configuration Composition

It’s no secret I am a fan of strong typing - not only do I talk and blog about it a lot, but I also have a library called Stronk which provides strong typed configuration for non dotnet core projects. The problem I come across often is large configurations. For example, given the following project structure (3 applications, all reference the Domain project): DemoService `-- src |-- Domain | |-- Domain....

November 9, 2017 · 5 min

Implementing Custom Aspnet Core ModelBinders

This post is a summary of a stream I did last night where I implemented all of this. If you want to watch me grumble my way through it, it’s available on YouTube here. In my Crispin project, I wanted the ability to support loading Toggles by both name and ID, for all operations. As I use mediator to send messages from my controllers to the handlers in the domain, this means that I had to either:...

September 22, 2017 · 5 min

Testing Containers or Test Behaviour, Not Implementation

The trouble with testing containers is that usually the test ends up very tightly coupled to the implementation. Let’s see an example. If we start off with an interface and implementation of a “cache”, which in this case is just going to store a single string value. public interface ICache { string Value { get; set; } } public class Cache { public string Value { get; set; } } We then setup our container (StructureMap in this case) to return the same instance of the cache whenever an ICache is requested:...

September 17, 2017 · 2 min

Repositories Revisited (and why CQRS is better)

TLDR: I still don’t like Repositories! Recently I had a discussion with a commenter on my The problems with, and solutions to Repositories post, and felt it was worth expanding on how I don’t use repositories. My applications tend to use the mediator pattern to keep things decoupled (using the Mediatr library), and this means that I end up with “handler” classes which process messages; they load something from storage, call domain methods, and then write it back to storage, possibly returning some or all the data....

September 9, 2017 · 2 min