My ‘Roman number’ convertor story

I wanted to try my hands on implementing a “Roman number’ convertor and do it in a new language and also do it object oriented. Started thinking about design and came up with RomanNumber, Numeral, RomanNumberDigitCognate as three objects that will abstract certain behaviours and data.

What I did not realise was how absorbed that I was getting into it, trying to solve a problem with a fixed scope (Only 4000 roman numbers in an identifiable pattern and only 7 characters to decode). To give an idea of my over engineering, here is a snippet of the validation. This one kept growing as I added more and more test cases.

I did not relent until I finished it, making it work for all set of test cases for conversion. After finishing, a day or two later a thought came to me. Why should a problem with fixed set of answers be programmed this way. Can’t it be solved in a different way.

It is when I thought let me study a bit deeper how each digits relate to each other mathematically without thinking about it in plain english terms. I split the validation, regex works wonders for validation in limited set. All you need is to make sure MDCLXVI comes in the right sequence and in right numbers.

The regex pattern is so simple and fool proof, did what 50+ lines of complex logic did

^M{0,3}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$

Next was the functional code, once I found the mathematical relation between the digits it was very easy to write the convertor in a few lines.

How easy it is to get carried away with the false sense of solving a problem when it is very simple if we spend a little bit more time before diving heads down. We have to spend more time understanding the domain in the shoes of the business, while not giving up on effective developer practices.

If a simple problem like this could get you trapped into over engineering what about complex domains?

Repo for reference — https://github.com/vinodkumaar/RomanNumber

Trim tab