It's fundamentally about decoupling. As the author of libfoo, I cannot keep up with all of the different Linux distros and how they do their thing. So you decouple the process by having two layers of maintainer; the upstream maintainer and the package maintainer. And I can't then also test my package with every other package on every other distro.
It has problems like anything else does, but it's pretty effective overall.
What's the alternative? If you will try installing random stuff you'll get dependencies hell. Another extreme is self contained software, when each application bundles its own dependencies. Android does that more or less. But such approach causes major bloat and also increases security risks because you need to patch each application and its dependencies (which are duplicated in the multiple variants) once vulnerabilities are discovered.
The bloat from self-contained software really isn't that much. It doesn't cause a space problem even on the small amount of space on an Android device.
It has problems like anything else does, but it's pretty effective overall.
What specifically do you find bad about it?