"Always do X" and "Never do Y" are almost always bad advice. Live by rules of thumb but don't become a zealot or rigid purist. Some duplication is acceptable, but lots is probably a sign that something is factored poorly or the wrong tool for the job.<p>Rules of thumb include but are not limited to: KISS, YAGNI, and DRY.<p>Another good rule of thumb is make things easy to figure out for future maintainers who you have yet to meet and may never. Programming is communicating with a future human, not just a machine. It's about people. (Insert Soylent Green jokes here.)<p>At least in ordinary CRUD, I find that simple, re-composable mini-components get me far more reuse than big swiss-army-knife-like components. Small components that can be copied, tweaked, remixed, or ignored with ease are more flexible.<p>Also, communicating via strings and string maps (dictionaries) makes them easier to mix and match than complex data structures/classes. String maps are relatively simple yet flexible for structure passing. You lose a little compile-time-type-checking by going string-centric, but there are work-arounds, such as optional named parameters that switch on type scrubbing when needed. (I love optional named parameters. Every language should have them.)