My previous posts were rather theoretical, a lot of philosophy, very little code. This time I’ll do almost the opposite, I’ll be actually writing a little system before your eyes, so there will be a lot of code. I will be referring to some concepts I was writing about previously, but this time I’ll not be discussing them, just applying.
There are many reasons I want to do this:
- I want to really show, that everything I was talking about (plus other things I didn’t mention so far) are actually doable. As Linus Torvalds puts it: “Talk is cheap, show me the code”.
- There are multiple technologies, that I never had a chance to actually try out like Java above 8 including modules, JUnit 5, Spring 5 with reactive web stack and HTTP/2 or Kafka.
- I’ve known theoretically both hexagonal architecture and domain driven design and I’d like to apply them somewhere.
- I’d like to find out if things, that I was doing so far in a specific way, could be done better with design patterns. I have no clue if I’ll find such functionalities, but I’ll try to keep my eyes open.
- When working with Spring applications, it’s very easy to let Spring go too deep into the application itself. I think I know what Uncle Bob means when he talks about “the main partition”, but I want to finally write an app this way to prove, that it’s actually possible. Also, my wife is now struggling with testing of a legacy application that’s using Spring Security, so I also want to find out how to test such applications properly.
- Whenever I’m looking for some examples of how to use something, they’re very simple, covering only the basics, and, quite often, providing very little value, especially when I’m struggling with putting together two different technologies. So I thought I’ll create a sample project putting together a few things, show how they work together (or against each other) in a much bigger and comprehensive “example”. I will also be “recording” changes to the code in git so you can follow the commits to see how the system was evolving.
- I’ve seen video series from Robert C. Martin and Sandro Mancuso “London vs. Chicago” and, honestly, I see some serious flaws in both their approaches (which they both also acknowledge). London school of TDD (outside-in with a lot of mocking) seems to me like it would, later on, prevent any refactoring, because every interaction between components is mocked and thus fixed. Chicago school of TDD (inside-out) seems to be avoiding this problem, but then the amount of speculation about what might come worries me. By the way, both of them agree to those points and provide ways of mitigating those issues. But, having watched an excellent video from Ian Cooper “TDD, where did it all go wrong”, I’d like to see how Kent Beck’s style TDD can this be done in practice and if this approach would lead to a different code (and issues most likely).
The app itself
As this is actually the least important thing in my endeavour, I’ll keep it simple. It will be a calculator with a REST interface. It will support a few basic operations like addition or multiplication, maybe a few standard functions like trigonometry, not much. It will be available to only registered users as a paid service so it will need to have things like authentication, user management and billing. Users might also belong to a bigger organisation like research institute. That would allow us to bill the organisations, not individuals.
And that’s it. Hopefully, this will already enable me to show/test/play around with things I mentioned above. If not I’ll be either adding new features, or I’ll be dropping some ideas. I guess it will depend on time and how much I really want to deal with a particular topic. Hopefully, given big enough audience, you could also try to convince me to add or remove something. I cannot tell anything right now for sure, nor I want to promise anything.
What’s not planned
As mentioned above, the only interface I’m planning right now is REST, any other GUI is a far bigger topic for me to include in here. I’m mostly a backend developer, just to try to catch up with frontend I would probably be creating a similar project to this one, but focused on Web UI. Maybe I’d take this application as a starting point, but that’s currently speculation on my side.
Deployment is also outside of scope. The app will be just a standalone JAR, most likely with only an in-memory DB, if necessary. I’m not expecting any need for something like Docker, Kubernetes or anything “cloudy”.
I’m not currently planning it, but maybe I’ll change my mind later on: operations and monitoring. Though I’d like to learn Spring Actuator more, I’m not sure this is the right time and place. If I find a good use case for it, I’ll not be thinking too long before including it in here though.
Although TDD should help me get a good architecture of the system, I should have an idea of how it should look like. As mentioned already, I’ll be using hexagonal architecture and I expect around 5 modules to appear:
- “business logic” so calculator itself,
- REST interface,
- user management,
The last one might require some explanation. The concept comes from Robert C. Martin, a.k.a. Uncle Bob, and it’s described in his “Clean Code” book. The general idea is, that each other module doesn’t know how to actually start, where to get its dependencies, etc. It’s the role of “main” module (or, as Robert calls it, partition) to be able to wire up and start everything. This should be the only place where Spring lives. Each module will also be a Java module so I will be able to enforce some additional restrictions as to code visibility.
Having modules clearly separated from each other, I can apply TDD to each one and test them only through their APIs. I’ll treat each module as a separate unit, just like Kent Beck intended. Most of my tests will be going for those module/unit APIs, but I’ll also have a few integration tests, starting with a REST call and going through the whole system.
According to DDD (domain driven design) every module might/should have its own data model, so please not be surprised if I find myself having, say, at least two different concepts of users or accounts, one for purpose of authentication/authorisation, one for billing and maybe yet another in calculator module.
There’s a bit of speculation above, I don’t know how many modules I’ll end up with. I also don’t know how many domain models I’ll have in the end, but most likely it will equal the number of modules. All this I expect to emerge by itself from the code.
One more thing, even though I’ll have multiple modules, I will not be creating microservices. I’m not too fond of them, because quite often they create much more problems than they actually solve. Plus this project is far too small to get any benefit from such architecture. But, having separate modules I could easily go that way if I needed to.
What can you expect
I’ll try to post regularly. The current plan is, that each post will cover one “tomato”, so 20 minutes of working with code. I’ll show you the code and changes I’m introducing. I’ll also try to explain my thinking, why am I doing the things I’m doing, and why in such a way. Like mentioned before, I’ll not be going too deep into explanations, just referring to a concept.
You can also follow the code on GitHub, where I’ll be pushing all the changes in small chunks.
So far I’m not planning any videos or screencasts, but if need be, I’ll think about them.
Without further ado…
That’s about it for an introduction. In next part I’ll get my hands dirty by starting actual implementation. Hope to see you there!