My personal view is that redundancy on stupid things is okay. That is, things that are very simple, you should be okay with doing over and over in multiple modules if you need it.<p>The experience that lead me to this was a particular team I was on where a previous developer had said "aha! All of these pieces of code relate to the same domain model, so we should build a common package of domain model objects and have all the modules share those objects! That way, we don't have to write them all over and over again!"<p>These weren't just model objects for data passing, but actual business logic inside these models. Usually very simple stuff, but occasionally a particular module would need some special logic on those objects, so in it went.<p>The problem was that over time, there modules started drifting. Their domains became different ever so slightly and the owners of those modules became different teams. Now if you wanted to modify the domain object, you had to check it wouldn't break code the other teams were developing.<p>It became a real mess. And all to avoid writing the same simple pojo classes more than once.
This guy definitely codes, I was nodding nearly every paragraph.<p>Redundancy vs dependencies is a constant battle, even internally or inside your own head.<p>Many times it depends on the project, team size and ability of libraries to be maintained whether budget, time or goal of the project and its lifeline.<p>For instance in gaming, you might have common libs for product purchasing, profile systems, networking, data, serialization, and platform libs to abstract calls. But systems like game objects, physics, gameplay and ui aren't as lib-able unless it is a series of the same type of game or system.<p>It is better sometimes to just get it out, prototype it and iterate to ship, then harvest and integrate useful/obvious items into dependencies/libraries for the next one. If you are always organizing to dependencies first, you will end up doing lots of unnecessary optimization and sometimes impact shipping speed.<p>The balance on this is a tough one to learn and changes as you grow more experienced.
Neither, they both can be good or bad. Part of being a professional is learning that there are no hard lines in software development. Being able to tell when something is good and when something is bad.<p>When I start developing I encourage redundancy. Premature abstraction is a very dangerous thing that can pin you into a tight corner.<p>Dependency is also fine, I keep things coupled together a bit close when they are still in development and malleable and decouple once they start to solidify.<p>It's my personal style of development when working alone. When working in a team, I follow whatever convention that works best for the team.
I am often of the impression that it is ok to start with many dependencies to get an application into an experimental state quickly, but ultimately this is extremely immature. As the application becomes polished over time and as there are refinements to increase performance, reduce complexity, and trim some fat many of the dependencies will go away. The reason why many dependencies peel off a maturing application is that as the programmers become more involved and aware of their knowledge domain they have to ask themselves if they can simply "do it better and faster on their own", which is likely.<p>Unfortunately many applications, or their programmers, never reach maturity. Also there is greater security and dependability in managing certain critical functionality more directly instead of relying upon support from a third party that may not exist with the same level of compatibility in the future.
You depend on code that is more abstract than yours. You replicate code that is at the same abstraction level of yours. You shouldn't even be touching any code that is less abstract than yours.<p>There is something to be said about libraries quality and trivial pieces of code. But I feel that this is just a rant about some environment that lacks a good command line parsing library.
On my last project since I was a one-man team, I erred way over on the side of dependencies. Thought I was being clever and organized for the first time, by encapsulating related things in related places and being a stickler about it. But in the quest to do that, I ended up with a large group of tightly-coupled trash cans!
In Go, "a little copying is better than a little dependency"<p><a href="https://www.youtube.com/watch?v=PAAkCSZUG1c&t=9m28s" rel="nofollow">https://www.youtube.com/watch?v=PAAkCSZUG1c&t=9m28s</a>
In the long run, dependencies are more expensive to work with, though
programmers usually don't see it nor admit it, as language package managers
hide the initial portion of the cost (the smaller one, but much better visible).
The main problem with redundancy is that every time you refactor you need to look for all the occurrences, and sooner or later you'll forget to update the change in one of the places. So in my book redundancy is bad almost always. On the other hand if it's only a few lines without extra dependences, it's often more readable to just repeat them, especially (and it's quite common) when you would need to add extra logic and conditions just to make that little abstraction work.
The command line example is a bit odd since any POSIX environment has getopt (GNU has getopt_long too) and most languages out there have well-developed command line parsing in their standard libraries (eg. Python's excellent argparse).