Microservices remind me of a particular C++ protocol implementation I wrote as a novice programmer. Since the protocol was structured, I had high level classes broken down into simpler classes. e.g.
virtual class Reader {
void read(Buffer *buf);
};
class TCharacter: public Reader {
TString *name;
TList<TStat> *stats;
...
};
class TStat: public Reader {
TWord32 *remaining;
TWord8 *percent;
};
class TWord32: public Reader {
uint32_t v;
};
class TWord8: public Reader {
uint8_t v;
};
And on, and on, and on, and on ...I thought it was cute that down to the simplest PODT, every type satisfied a well defined `Reader` interface. I hand wrote many constructors, deconstructors, read and several other interface definitions for each type.
Elegant, arguably. Inefficient, yes. Overly complex, undoubtedly.
Every argument for microservices has in some way reminded me of this code, with it's well defined interfaces and overly verbose implementation.
My current strategy is to utilise the crap out of language features to safely achieve what I want in the minimal amount of code possible. In C++ this would be done by initialising the protocol structure classes straight out of the memory buffer, using #pragma pack as required. No error prone constructors / deconstructors / read() required.
Haskell and Scala are two languages I use a lot, and each have powerful type systems which I can use to prevent myself from doing something stupid. Programmable macros are great for removing boilerplate. Want less technical debt? Write less code.
In my own controversial opinion, if somebody can't work out how to modify my code because they can't work out how to correctly update the type definitions, that person has no business modifying my code. Problem solved! Interfaces are well defined and modifiable only by people who truly understand the code.