Also, the claim "In the historical Dark Ages, religion put down science" is simplistic. If by "Dark Ages," the author means the time between the fall of Rome in the west and the Carolingian Renaissance in 800, there was no institution maintaining science, but there happened to be institutions maintaining religion. During this time, what scientific knowledge that was preserved in the west was preserved by monks copying manuscripts. If the author means to refer to the whole Medieval period, then many of the most famous scientists were clergy, and many scientific institutions grew out of religious institutions, so again the claim is confusing.
It's unfortunate that the author chose to distract from a good point by using a problematic metaphor.
Here's my dismantling... The Carolingian Renaissance was not a renaissance. Frankia had never really been a part of the ancient civilization of Greece, Rome and "eastern lands." It was a roman outpost, for a time, but they never had urban civilization, widespread literacy, political unity or such. Same for the "Scottish Renaissance" or whatnot. The term makes sense for Italy, but that's about it. Before this period, it's all darkness... apart from an occasional roman flashlight.
In any case, the term "dark ages," at core, just means the absence of historical records.
https://slatestarcodex.com/2017/10/15/were-there-dark-ages/
Previous HN discussion of this article:
The author is just trading one set of hyped buzzwords (microservices/k8s/devops) for another (oop/solid/ddd).
It doesn't help when he claims that his approach is proved by science!!
There's no approach to software development that has been proven by science.
As far as I can tell, the search for the right methodology is part of the problem.
Instead of just writing the most sensible and simple code that would work, you have to adhere to some methodology.
Object Oriented Programming is not going to solve your maintenance problems and development speed. In my experience, it only makes it worse.
As far as I can tell, the author acknowledges that his methodology is not working for a lot of people, but he attributes that to "you're not doing it correctly" which is typical of advocates of OOP/SOLID/etc.
But this same excuse can be said about microservices. So what is the point?
The author spends a lot of time talking about how to talk to stake holders to understand the requirements.
OK. I'm totally behind the developers having complete understanding of what they are working on and what the expected results roughly should be like.
But as far as I can tell, this has nothing to do with domain driven design _per se_.
You can have complete understanding of the project, and implement the project successfully, without ever bothering with DDD.
I guess for some it is simply hard to grasp that one can have good understanding of software development without cramming endless design patterns and methodology acronyms.
It’s easy to say „just write simple code”, but how do you do it? It’s not an advice someone can follow. Complex domains have many challenges where having patterns helps.
I see it all the time devs off-roading a relatively simple project to try out the latest tech. It always ends up taking much longer and leaves behind a mountain of technical debt.
That's ok though they'll leave in 6 months to go wreck havoc on another company's code base.
The microservices there were anything but. Not only tightly coupled, but coupled at build time, such that we had a mountain of custom Ruby libraries written by one person to parse and publish Apache Ivy files no matter the underlying build and packaging system, to construct dependency trees and build orders for this massive Jenkins infrastructure that rebuilt the world several times a day. It got even worse, because the development teams were building fat jars, then the pipeline team was putting those in fat containers, then we were shipping the containers, except across an air gap. So we're generating gigs of data every hour that some poor souls have to physically burn to DVDs and sit around waiting for hours while virus scanners approve it to go into the runtime system.
But I don't think the issue was so much a dark ages problem that nobody understood what we were doing. It was just myopia. Nobody understood the impact their decisions had on downstream and upstream teams. Architects were pitching great ideas to customers, managers were making tremendous promises, and neither had any idea that the as-built system came nowhere near matching the glorious vision they drew up on a whiteboard. And the developers didn't know the whiteboard vision even existed. They just saw tiny chunks of single-sentence Jira tickets with no context and no idea how they fit into the larger system.
It's the Buddhist koan thing about 10 people looking at an elephant but nobody seeing an elephant.
This is the answer. Most of us are in the weeds throwing darts.
I've experienced all of these strategic patterns mentioned, and it's still been a massive clusterf*ck of failure.
DDD attempts to solve the right problems, but so does everything else, and adding process when there's an incentive and cultural misalignment doesn't actually help.
Every success (including major ones, going from so risky the VP doesn't even want to attempt it to best thing ever delivered by the department style of things) I've seen has been due to two things. First, dev believing that their responsibility was to understand and solve a particular problem, and that they were empowered to actually do that. Second, product believing that what they'll be evaluated on at the end of the day is if a valuable solution is provided. Both of these are predicated on upper management creating incentives for doing them, rather than all the other BS that upper management can end up prioritizing instead (i.e., status reports, documentation, checklists, roadmaps, etc).
With those two things in place, you'll figure out a process that works. You want to use DDD? Fine. You don't want to? You don't need it. You can have all the same information you'll get via Event Storming and etc collected and shared verbally via tribal knowledge (ideally not just this, but I've done it successfully, if with some obvious risk), or written in wikis, or whatever, and be successful.
Without those two things? The devs will be bored as product talks at them rather than to them as they move stickies around, the stories will still reflect nothing of value, the actual work will be extremely low quality and will be constantly in need of rework (both due to quality and due to actual value), there will be constant asks for documentation that no one will read, and constant meetings to prepare for and explain status.
> Some engineers tell me they are “just engineers”. They don’t care too much about who uses their software or why. They are just implementing, say, JIRA tasks – building services with some bytes on the input and some bytes on the output.
I think this might be one reason why I didn't stay in my previous job as an engineer at a big tech company. I do care about who's using my software and why, especially since I work in an area (accessibility) that's all about the human factors.
But now that I'm a cofounder and one of only two developers at a tiny company, where I have the power that I wanted to shape the whole user experience, I find that I too often get side-tracked trying to make the technically best decision on some tactical thing, e.g. choosing the best distro for a container, as if I were specializing in that area, when I should just quickly choose something popular and good enough so I can stay focused on the big picture. As is so often the case, I guess I'm trying to have it both ways.
_Now_, we choose off-the-shelf X because it will get us started and we have 99 other things to bootstrap.
_Next_, we throw the original away and plug in better tech Y.
_Later_, when resources are not an issue, we’ll use Kubern... tech Z. :)
Engineering isn't about coding, coding is simply a tool to achieve results. If your organization managed to silo it's engineers into ticket-coder orgs, there's something wrong with your company.
There is nothing a microservice does for maintainability that an interface and modularity won’t do.
It only makes sense if there are specific resource intensive things that need to scale separately, or if you have more than one language or runtime.
It’s probably something pushed by cloud providers to increase lock in and use more resources, since adding self hosting capability to a microservice based system that is dependent on Kubernetes is going to be that much harder.
Reliability. There is a chance that one microservice crash looping does not bring the whole system down. This would not be an advantage if languages were better at isolating failures but they aren't.
Independent release cycles. It is good to be able to upgrade only one service. For example if something goes wrong, you roll back only one service. You also have a smaller code base to debug.
Runaway resource consumption. A memory leak or a logs explosion only affects one service. This arguably is a version of "scales independently".
Above stuff is from my experience at Google. YMMV. I can imagine that a badly designed microservice architecture does not bring these benefits.
Also, microservices are much better at isolating faults than any traditional langauge is, even for pretty systemic faults such as memory leaks - if each service is running in some container, storing most state in a DB instead of memory, users may not even notice when it crashes with an OOM, something no runtime I know could realistically handle (unless you do gargantuan work to manage memory explicitly for this goal).
> It’s probably something pushed by cloud providers to increase lock in and use more resources, since adding self hosting capability to a microservice based system that is dependent on Kubernetes is going to be that much harder.
The whole point of Kubernetes is the ease of switching between clouds or cloud and self hosting. As long as your application only depends on Kubernetes abstractions, the cost of moving from EKS to AKS or to Kubernetes on bare metal is going to be relatively small - probably smaller than most deployment options that can handle a similar scale and reliability.
Technically I agree. It doesn’t really do anything that decent interfaces and loose coupling do not.
A good example - I bet modern graphics cards and simple what that does to neural nets are going to basically erase a lot of former truths about text search, image interpretation and when it is appropriate to use either. And another - rapid upticks in internet/mobile availability reshaped what was true about the web 10 years ago.
It is hard to build well & to last in such shifting environment. Low quality, fast solutions have an edge. In time the wheel will turn. There will be a sudden turning point where spending 5 years on really ironing out bugs and performance tuning starts to make a big difference.
In short, any problems have nothing to do with modelling techniques or the approach taken by software practitioners.
It depends a lot on the domain on which you are working on. In places where I worked, such big changes could be encapsulated and separated from the domain logic (by using Clean Architecture, for example).
This is where modelling techniques are useful - with proper exploration you can create proper boundaries that will save you from such big changes. The only thing that is constant is change. It's all about being prepared for that.
I rather don't want hardware innovation to slow down or stop.
My one experience with DDD and microservices was more the reverse; DDD was applied through code patterns but had no organizational/proces adoption. This caused bloated over-engineered microservices where simple things took way too much code and time to figure out.
Sounds like DDD is just another set of buzzwords to learn but I like the warning that you should use common language when communicating across the developer-user membrane.
Ina nutshell, that’s the problem with almost all software development methodology — we don’t/can’t frame any of them in a falsifiable manner, so it’s difficult for the field to progress, even over decades. Bad ideas keep hanging around, and can’t be filtered from good ones. One can always keep playing “No true Scotsman” games on anybody’s experience, so most discussions end up devolving into froth.
Evans - Domain Driven Design
If I have a monolith where each operation synchronously delegates to other modules within the same process, then this system may be tightly coupled. However, even if it is, API calls are fast and predictable.
If I rewrite the same monolith into microservices, where the same API calls are replaced with HTTP requests to the other services, my system is still tightly coupled. Each API call now incurs xx ms of latency and risk of transient failure. I could deploy each module independently, but doing so would cause other modules to fail. Arghh! Arguably the degree of coupling hasn't changed here, but the implications are that much more severe.
Loosely coupled microservices usually use some highly available message queue or streaming system so services can operate independently. You can still be tightly coupled in this architecture though. If you issue a message, then immediately wait for a response message, you're in pretty much exactly the same situation as above.
Actually loosely coupled services usually issue and consume messages separately. In this case, if one service goes down a backlog builds, but the other service can still push messages on to it.
Some loosely coupled microservice architectures (Starling Bank comes to mind) do use synchronous HTTP messaging. Sometimes you want the services themselves to ensure delivery of messages.
It isn't inherent to microservices, but it is common enough that many people will work on a distributed monolith.
The advantage to micro services is that you can develop, test and deploy/release them independent of other components in the system. But there are plenty of other kinds of dependencies that can exist between components and if you don't don't manage them somehow, your system will drift toward a "ball of mud" where everything is dependent on everything else and any change is cross-cutting and difficult. That's true whether you have micro services or not.
I'm actually a big fan of modular, properly implemented monoliths. In the first blog article I was even showing that it can be actually an implementation detail if an application is monolith or microservice: https://threedots.tech/post/microservices-or-monolith-its-de...
> It’s a key for achieving proper services separation. If you need to touch half of the system to implement and test new functionality, your separation is wrong.
The defining characteristic of the dark ages is a lack of historical records, and a general idea of stagnation. A period we could nearly seamlessly cut out of history.
It is certainly not the case today, a lot is being recorded, we do a lot of things, so if we have to define a software dark age, when would it be?
I'd go with 2000 (dot com bubble burst) to 2007 (first iPhone). For the end date, the iPhone is not that important, but it marks the rise of "big data", smartphones, and mobile internet.
The problem with Blind is it attracts the former group almost exclusively. I'm happy at my job, downloaded Blind once to see the content, and deleted it almost immediately. I have no interest in reading toxic posts by anonymous folks struggling at my company.
All else is noise.