This is not a "right answer" question. I am primarily looking for recommendations for books / resources / blog posts. There will likely be followup questions.
I'm primarily interested in Rust resources, but given the nature of the topic, I'm open to generic / non-Rust advice too.
here's the issue: Back when I was dealing with dynamically-typed, no static typing languages, there was this productivity barrier that I hit at around 10k lines of code. Refactoring becomes a drudge. I rename something, I don't find all refs, something else becomes nul/nil/undefined, and I get a runtime error. Because of this, I am reluctant to refactor. Bad design accumulates. And dev time slows down.
With Rust/IntelliJ, renaming-refactoring is no longer an issue. IntelliJ resolves all refs (outside of macros), and those IntelliJ misses, the static type checker catches. However, at around 50k-100k loc, I am still running into a "refactoring becomes a drudge; shitty design accumultes" problem, largely due to "everything knowing too much about each other."
I'm looking for concrete advice from those who have scaled codebases from 50k-100k LOC to the 500kloc+. In particular, I am curious about things like:
-
how do you architect large codebases with "components" that are easy to replace / refactor ? One approach I have been thinking about w/ regards to this is Programming against traits in Rust - #19 by zeroexcuses
-
how do you architect large codebases that are easy/productive to develop against ? (one measure is: minimizing the # of concepts the coder has to keep in mind; another is components with "predictable" behaviour, etc ...)
-
One thing I'm really drawn towards is:
"Show me your flowchart and conceal your tables, and I shall continue to be mystified. Show me your tables, and I won't usually need your flowchart; it'll be obvious." -- Fred Brooks, The Mythical Man Month (1975)
This includes Entity-Component-System design. Even outside the benefits of cache locality, I like the way how there is a central store for state (Entity-Component), and update rules are coded up in Systems (which feels like loose coupling and allows independent refactoring / updates).