January 1st, 2020

First to give you some context, I only became aware of the phrase "First Principles" recently.

I don't quite know everything there is about it, but I have started to look at this from a software development perspective in the work I create and I can tell you how I am applying what I know about "First Principles" to what I am doing.

First of all, you need to start somewhere. First Principles (FP) isn't really my starting point.

My starting point is to just build something based on how I have done things in the past. The mentality I find necessary to develop with FP in mind is to be completely willing to move backwards as far as it takes to do it right.

This is very challenging. Deadlines may even prevent it. So you need enough time (a couple months) to really start again from a different angle and still be able to meet a deadline.

In my case, I had built a system before which did almost all of the same things that this system did. But everything was done just a little bit differently.

My first inclination was to get the system back to what it was. However, I found this implementation had constraints which made the UX horrible.

It had to be undone. In this case, it was that the way I built the system originally, it required the user to be logged in. The new way would make it more engaging for the user if this barrier to entry was removed. After all, it was a completely different use case.

It took more than a week just to get back to step 1. Which was now step 1 after a new step 0. Step 0 is stubbed in for now.

So good, I can identify all the remaining steps for the UX. There are about 5 more by the time the customer has product in hand and then product registration.

For each step, I am creating a good default and an inherited abstraction layer to allow new implmentations/integrations and customisation through each step of the way. I assume each step may need to integrate through a third-party API. Perhaps a different bank or different shipment system.

And I thought this would be great. But then I got a better idea.

You see, the problem with my system was that it had all the steps in order. A static ordering of steps. And I was going to make services which would automate the progress of steps for clients who wanted to skip some steps. And adding more steps would be a challenge that could potentially impact stability.

But the static nature of the code forced one step after the other hard coding the order.

So, looking at having another 4 weeks to implement, I decided this was no good. If I am to build the world's best system, this static order will not be it.

I was expecting to give a presentation later this week which I found out would be next scheduled Tuesday. Had the presentation been this week, this system could have been forced into an inferior rigid static model that would be destined to be out-shown by another future system.

Do I have enough time by Tuesday to start at the beginning of a dynamic state machine? I am not sure. I may update this post in the future as to what happened. Luckily, I haven't committed to having anything specific for Tuesday and I haven't got API access either.

I really like this new design model. Not only will I be able to remove states and save time implementing useless services that bypass, and re-order states so that money collection -> delivery could be inverted to delivery -> money collection (COD style) but I can also create combo states that combine contractual agreement & payment collection in 1 step or separate them into 2 steps. I can also inject new steps. Beyond that I can override any 1 step with a custom third party integration.

The only thing I can't do is apply multiple step options to a single step.

While it isn't the most ideal outcome, I am not certain this would ever get used and therefore likely never bring the additional dev time into fruition.

The other aspects, I am sure will be used as we have differences in future requirements for different implementations as well as the knowledge that past projects behaved differently as well. But the old way could be migrated into this new way in the future.

Posted In:

Software Developer always striving to be better. Learn from others' mistakes, learn by doing, fail fast, maximize productivity, and really think hard about good defaults. Computer developers have the power to add an entire infinite dimension with a single Int (or maybe BigInt). The least we can do with that power is be creative.