I've written a lot of complex stuff. In fact, I'm doing it right now.
There needs to be a "sweet spot," where we have enough complexity to achieve goals (which can be business and cultural, as well as technical), and as much simplicity as possible.
A lot of folks think that using dependencies makes the project "simpler."
It does, for the final implementation team, but that complexity still lives there; along with a whole bunch of cruft, tech debt, potential legal issues, security issues, etc.
Unfortunately, you can't do complex stuff, simply. Some level of complexity is always required. Managing that complexity is where we get to play adults.
Right, using too dependencies don't make things simpler. They make them easier as long as the dependencies can do exactly what you need. However sometimes you come to a point where the dependency can't do something that's needed (often by the time I realized a third party lib can't do sth, I could have implemented it by myself without the dependency) or where you've accumulated so many dependencies that they conflict with each other or where connecting two different libraries is the really hard part. No silver bullets.
Figuring out the sweet spot in architectural design seems to me still an art/craft, that comes from intuition and by experience.
[As far as dependencies... using dependencies may sometimes be simpler than the alternative(s), and sometimes not, sure. It depends on the nature of the dependencies, the problem, and the alternatives. :) ]
Complexity is also one of the best moats in the business, if you have a "gross" problem with many edge cases there's few people who will want to eat your lunch, and most next generation up and comers often tout their simplicity compared to your old complex product because they certainly cant argue feature parity ;)
> It does, for the final implementation team, but that complexity still lives there; along with a whole bunch of cruft, tech debt, potential legal issues, security issues, etc.
I call this squeezing the balloon, the complexity doesn't go anywhere, it's inherent to the requirements of the system. You just put it somewhere else.
This is just code factoring at a macro(-ish) level.
For well maintained deps there is the extra boon that it takes work off your hands though. For instance building a React app with Next.js saves you from ever having to deal with webpack and you get big upgrades for free.
> For well maintained deps there is the extra boon that it takes work off your hands though.
Absolutely. Nowadays, it's pretty much impossible to write anything without some level of dependency; even if just the development toolchain and standard libraries.
The problem is that a lot of outfits and people are releasing subpar dependencies that smell like the kinds of high-quality deps we are used to, but, under the hood, are ... not so good ...
Nowadays, it's fairly easy to write up a Web site with lots of eye candy, and gladhand a bunch of corporations, enough to get their brand onto your Step and Repeat Page, so it looks like your dependency is "big league," when it is not. In fact, the kinds of people that couldn't design a complex system to save their lives, are exactly the ones that are experts at putting up a wonderful façade.
What gets my goat, are proprietary SDKs, often released by peripheral companies. These can be of abominable quality, but are also the only way to access their products, so you need to load a bloated, sluggish, memory-leaking, thread-safety-is-optional, crashes-are-so-much-fun library into your app, and hand that library the keys to your sandbox, just so you can get at the device.
I've been writing exactly that kind of SDK for years, and know that we can do better. I'm a big proponent of open SDKs, but many peripheral manufacturers are absolutely dead-set against that.
These SDKs often mask significant complexity. That's what they are supposed to do. They also generally translate from the workflow of the device, to one that better suits application developers. Some SDKs are just a simple "glue" layer, that directly map the low-level device communication API to the software. That can be good, sometimes, but is usually not so good.
There needs to be a "sweet spot," where we have enough complexity to achieve goals (which can be business and cultural, as well as technical), and as much simplicity as possible.
A lot of folks think that using dependencies makes the project "simpler."
It does, for the final implementation team, but that complexity still lives there; along with a whole bunch of cruft, tech debt, potential legal issues, security issues, etc.
Unfortunately, you can't do complex stuff, simply. Some level of complexity is always required. Managing that complexity is where we get to play adults.
T.A.N.S.T.A.A.F.L.