The older generation are in this place because back then none of the technologies you listed existed and so they had to know the more low level things.
A book that might help some of your knowledge gaps (at least directionally) is The Imposter's Handbook[1] by Rob Conery.
If you're specifically aiming to get away from CRUD take a look at the various Domain Driven Design books by Eric Evans[2] and others. This is the opposite direction to your ask though (more high level than low level).
If you want to go deeper in Java, read Effective Java[3] and Java Concurrency in Practice (JCIP)[4]
Lastly, if you want to experience the reasons why some of that early comp-sci stuff happened the way it did, playing with expensive hardware is the least effective way to find understanding of constraints. Instead consider grabbing devices with significant limitations like an Arduino, ESP32, or similar (I'm partial to the Wio Terminal[5] and M5Stack[6] as interesting easy to get started devices, but others would suggest various Arduinos or Raspberry Pi devices). Realistically you're going to learn much more by coming up with a self-challenging project and completing it than just by learning it for the sake of learning.
[1]: https://bigmachine.io/products/the-imposters-handbook/
[2]: https://www.amazon.com/Domain-Driven-Design-Tackling-Complex...
[3]: https://www.amazon.com/Effective-Java-Joshua-Bloch/dp/013468...
[4]: https://www.amazon.com/Java-Concurrency-Practice-CONCURRENCY...
[5]: https://www.seeedstudio.com/Wio-Terminal-p-4509.html
[6]: https://m5stack.com/
In your examples you need to add extra layers, just like you would do with the microservices.
There would be the DTOs that represent the actual data that gets across the models, the view models that package the data together as it makes sense for the views, the repository module that actually abstracts if the data is accessed via SQL, ORM, RPC or whatever.
You should look into something like:
"Domain-Driven Design: Tackling Complexity in the Heart of Software"
https://www.amazon.com/Eric-J-Evans/dp/0321125215
"Component Software: Beyond Object-Oriented Programming"
https://www.amazon.com/Component-Software-Beyond-Object-Orie...
Which brings be back to the original objection. I think this is true most of the time, except when it's not - which is your core Domain Model. The first 1/2 of the Blue Book[1] lays out straightforward means to arrange code, functions, data/state and related behaviours in a way which can be managed and maintained over time. This is pretty important as most folks who've spent any length of time maintaining vast applications will know that it's incredibly hard to reason about a first-class concept in an application without clear boundaries around said concept, it's structures and it's behaviour. Most of us are unlucky and find this scattered across the landscape. Few applications take the focus to "model" these concepts clearly.
Does this modelling have to be done with "Domain Model", or DDD, or something else that can be loosely coupled with OOD - probably not. But another developer absolutely has to be able to reason about said structures and behaviour. They have to be able to read it easily and grok it quickly. And having done that, they don't want to be surprised by some distant missing element, 20 calls or 1000 lines or 15 modules (repos, submodules, etc, etc) away! This is possibly the biggest time-sink and therefore "cost" of development. One could also take this further and postulate that about 1/2 of us are employed as a direct result of applications whose core concepts are so poorly designed or hard to reason about, that a massive volume of work (time?) is dedicated to unwinding the ambiguity that results.
I don't want to suggest that OOP or OOD/DDD/{other modelling process} would necessarily fix this, but the attempt to clarify and find a means to make modelling these critical concepts easier and less costly is admirable IMO.
It's ok if your infrastructure takes a different approach, or is "functional" or "dynamic" in nature. If your test suite uses completely different patterns and paradigms because the tooling makes that easy then - awesome! But if the core model/concepts of your application are hard to understand, reason about, and therefore maintain, then you're pretty fucked.
OO doesn't "suck". It's spirit is just largely lost and like many other things in life, it's been hijacked and mutilated into something many of us come to loathe because we've never seen it deliver on the promises. I guess we will be having this conversation again in another decade about something else that's hugely popular right now.
[1] https://www.amazon.com/Domain-Driven-Design-Tackling-Complex...
https://www.amazon.com/Domain-Driven-Design-Tackling-Complex...
https://www.amazon.com/Clean-Code-Handbook-Software-Craftsma...
https://www.amazon.com/Clean-Architecture-Craftsmans-Softwar...
https://www.amazon.com/Patterns-Enterprise-Application-Archi...
https://www.amazon.com/Refactoring-Improving-Existing-Addiso...
https://www.amazon.com/Code-Complete-Practical-Handbook-Cons...
https://www.amazon.com/Pragmatic-Programmer-Journeyman-Maste...
https://www.amazon.com/Mythical-Man-Month-Software-Engineeri...
And just because it’s asked at every interview.
https://www.amazon.com/Design-Patterns-Object-Oriented-Addis...
I’m focused on AWS these days, but a lot of these principals are universal.
https://d1.awsstatic.com/whitepapers/architecture/AWS_Well-A...
* Enterprise Integration Patterns (basically an entire book about messaging architectures) [1] * Vaughn Vernon's books and online writing [2], * Domain Driven Design by Eric Evans [3], * and most of what Greg Young, Udi Dahan, and that constellation of folks has done online (lots of talks and blog articles.)
Depending on your platform of choice, there may be others worth reading. For my 2¢, the dragons are mostly in the design phase, not the implementation phase. The mechanics of ES are pretty straightforward—there are a few things to look out for, like detection of dropped messages, but they're primarily the risks you see with any distributed system, and you have a collection of tradeoffs to weigh against each other.
In design, however, your boundaries become very important, because you have to live with them for a long time and evolving them takes planning. If you create highly coupled bounded contexts, you're in for a lot of pain over the years you maintain a system. However, if you do a pretty good job with them, there's a lot of benefits completely aside from ES.
[1] https://www.amazon.com/Enterprise-Integration-Patterns-Desig...
[3] https://www.amazon.com/Domain-Driven-Design-Tackling-Complex...
Boundaries are by domain, and yes that's not a simple thing to define. Sometimes, domains have varying interfaces, which makes building micro-services more complex, especially when trying to adhere to REST/Swagger standards (something I'm not overly find of).
But keeping things as simple as possible is really the best approach.
All micro-services should be small. When I see someone say "big", then I'm guessing there are a lot of ad-hoc actions...those need to be broken down into their proper domain or relegated to a query service.
I started changing my way of looking at identity by reading the rationale of clojure (https://clojure.org/about/state#_working_models_and_identity) -> "Identities are mental tools we use to superimpose continuity on a world which is constantly, functionally, creating new values of itself."
The timeless book "Data and reality" is also priceless: https://www.amazon.com/Data-Reality-Perspective-Perceiving-I....
More specifically concerning the article, I do agree with the point of view of the author distinguishing access by identifier and hierarchical compound name better represented as a search. On the id stuff, I find the amazon approach of using URN (in summary: a namespaced identifier) very appealing: http://philcalcado.com/2017/03/22/pattern_using_seudo-uris_w.... And of course, performance matters concerning IDs and UUID: https://tomharrisonjr.com/uuid-or-guid-as-primary-keys-be-ca....
Happy data modeling :)
EDIT: - add an excerpt from the clojure rationale
It's not relatively new. That “transaction file” thing in your database? Event Sourcing.
https://goodenoughsoftware.net/2012/03/02/case-studies/
> If you’re not looking at the public chain, you’re wasting your time
I disagree. Not having a single point of failure (one place that can get hacked) is valuable.
> From a trust perspective, it makes no difference if your banking cartel is writing to a Quorum, Hyperledger, or Kafka instance.
Of course it does. The protocol of blockchains makes them work with "proof of X". Appending to any event store, whether in Kafka or SQL does not require proof of anything.
> Blockchains are built for trust, databases for throughput. Event sourcing allows us to achieve a hybrid model with characteristics of both.
No, the reason blockchains can't have high throughpout / almost infinite horizontal scalability... is because there's a logic check. E.g. in bitcoin, you can't send more bitcoins than you have a balance. Event sourcing gives you the high throughpout if there's no logic checks across aggregates --- if there are, you won't have immediate consistency, and you have to be ready for compensating events.
I recommend two books, that cover event sourcing from a Domain Driven Design perspective. The consequences are similar.
https://www.amazon.co.uk/Domain-driven-Design-Tackling-Compl... https://www.amazon.co.uk/Implementing-Domain-Driven-Design-V...
-----------------
If that doesn't do it for you, please just remember the good old CAP theorem.
A Pattern Language, Alexander and Ishikawa and Silverstein http://amzn.to/2s9aSSc
Advanced Programming in the Unix Environment , Stevens http://amzn.to/2qPOMjN
Algorithmics: the Spirit of Computing, Harel http://amzn.to/2rW5FNS
Applied Crytography, Wiley http://amzn.to/2rsULxS
Clean Code, Martin http://amzn.to/2sIOWtQ
Clean Coder, Martin http://amzn.to/2rWgbEP
Code Complete, McConnel http://amzn.to/2qSUIwE
Code: The Hidden Language of Computer Hardware and Software, Petzold http://amzn.to/2rWfR9d
Coders at Work, Seibel http://amzn.to/2qPCasZ
Compilers: Principles, Techniques, & Tools, Aho http://amzn.to/2rCSUVA
Computer Systems: A Programmer's Perspective, O'Hallaron and Bryant http://amzn.to/2qPY5jH
Data Flow Analysis: Theory and Practice, Khedker http://amzn.to/2qTnSvr
Dependency Injection in .NET, Seemann http://amzn.to/2rCz0tV
Domain Driven Design, Evans http://amzn.to/2sIGM4N
Fundamentals of Wireless Communication, Tse and Viswanath http://amzn.to/2rCTmTM
Genetic Programming: An Intrduction, Banzhaf http://amzn.to/2s9sdut
Head First Design Patterns, O'Reilly http://amzn.to/2rCISUB
Implementing Domain-Driven Design, Vernon http://amzn.to/2qQ2G5u
Intrduction to Algorithms, CLRS http://amzn.to/2qXmSBU
Introduction to General Systems Thinking, Weinberg http://amzn.to/2qTuGJw
Joy of Clojure, Fogus and Houser http://amzn.to/2qPL4qr
Let over Lambda, Hoyte http://amzn.to/2rWljcp
Operating Systems: Design and Implementation, Tanenbaum http://amzn.to/2rKudsw
Parsing Techniques, Grune and Jacobs http://amzn.to/2rKNXfn
Peopleware: Productive Projects and Teams, DeMarco and Lister http://amzn.to/2qTu86F
Programming Pearls, Bentley http://amzn.to/2sIRPe9
Software Process Design: Out of the Tar Pit, McGraw-Hill http://amzn.to/2rVX0v0
Software Runaways, Glass http://amzn.to/2qT2mHn
Sorting and Searching, Knuth http://amzn.to/2qQ4NWQ
Structure and Interpretation of Computer Programs, Abelson and Sussman http://amzn.to/2qTflsk
The Art of Unit Testing, Manning http://amzn.to/2rsERDu
The Art of Unix Programming, ESR http://amzn.to/2sIAXUZ
The Design of Design: Essays from a Computer Scientist, Brooks http://amzn.to/2rsPjev
The Effective Engineer, Lau http://amzn.to/2s9fY0X
The Elements of Style, Strunk and White http://amzn.to/2svB3Qz
The Healthy Programmer, Kutner http://amzn.to/2qQ2MtQ
The Linux Programming Interface, Kerrisk http://amzn.to/2rsF8Xi
The Mythical Man-Month, Brooks http://amzn.to/2rt0dAR
The Practice of Programming, Kernighan and Pike http://amzn.to/2qTje0C
The Pragmatic Programmer, Hunt and Thomas http://amzn.to/2s9dlvS
The Psychology of Computer Programming, Weinberg http://amzn.to/2rsPypy
Transaction Processing: Concepts and Techniques, Gray and Reuter http://amzn.to/
Types and Programming Languages, Pierce http://amzn.to/2qT2d6G
Understanding MySQL Internals, Pachev http://amzn.to/2svXuFo
Working Effectively with Legacy Code, Feathers http://amzn.to/2sIr09R
Zen of graphics programming, Abrash http://amzn.to/2rKIW6Q
[1] https://www.amazon.com/Domain-Driven-Design-Tackling-Complex...
[2] https://www.microsoftpressstore.com/store/object-thinking-97...
MartinFowler DDD blogs: http://martinfowler.com/tags/domain%20driven%20design.html Book: https://www.amazon.com/Domain-Driven-Design-Tackling-Complex...
The main compliment I'd suggest to this approach is Eric Evans' book Domain-Driven Design: https://www.amazon.com/Domain-Driven-Design-Tackling-Complex...
In a bottom-up approach, you can often break things down in a variety of ways. But the most stable/useful ways are often the ones that align with the conceptual model of the domain. If I notice that certain data and behavior goes together with incoming money, I might call that an InboundMoneyWorkingUnit. But if I talk to people who've spent years working in the domain, I'll realize the object should be called Payment, and their description of what a Payment does will inform my hunt for other objects and methods.
I think "conceptual debt" is a poor choice of phrase here, as one important kind of technical debt is the sort of software design debt where your domain model ends up being a poor fit for your domain, often because the domain concepts themselves shift. (For those interested, "Domain-Driven Design" is a great book relating to this [3].)
I also find the "worse than technical debt" headline irritating. It's the sort of, "the thing I specialize in is way more important than the thing you specialize in" thinking that is poisonous in a team environment. Which one is actually worse depends a lot on your product and your business conditions.
[1] https://medium.com/@vijayssundaram/user-experience-debt-c9bd...
[2] http://andrewchen.co/product-design-debt-versus-technical-de...
[3] http://www.amazon.com/Domain-Driven-Design-Tackling-Complexi...
It's nice to have language support for functional style (let, for example) where that is appropriate for the problem at hand, but you can write in that style without the language support easily enough.
On the other hand, when FP style is not appropriate for the problem at hand, it really, really gets in the way, and that's the case a lot of the time. Many if not most problems (outside of writing compilers for FP languages) don't really fit the functional style, and have to be made to fit.
Experienced devs will choose appropriate tools for the problem at hand. Me, I like adaptive tooling that I can bend to fit the problem, which is why I like dynamic OO languages, internal DSLs and Domain Modeling[2] in general.
In fact, I think the current tools are still a little too inflexible for this, which is why I am creating a language to address some of these issues: http://objective.st
FP seems to be more about bending the problem to fit the tooling, which I guess may work for a specific kind of mindset.
[1] http://en.wikipedia.org/wiki/Higher_order_message
[2] http://www.amazon.com/Domain-Driven-Design-Tackling-Complexi...
[1] http://www.amazon.com/Domain-Driven-Design-Tackling-Complexi...
You can learn more about it from this book:
Domain-Driven Design: Tackling Complexity in the Heart of Software
http://www.amazon.com/Domain-Driven-Design-Tackling-Complexi...
http://www.amazon.com/Domain-Driven-Design-Tackling-Complexi...
I might suggest something more above the free of technology and more in the design of software. Ideas that last are the ones around approaches to design vs. actually technology that they are implemented with.
My co-worker (a younger version of me, actually and way smarter is wise beyond his years) gave me this book - which is as old as my career and has relevance on how we design software at my day job.
https://www.amazon.com/Domain-Driven-Design-Tackling-Complex...