3 ms·
I have been down both roads. I’ve seen unwieldy abstractions reduce a codebase down to a giant pile of edge cases, and I’ve seen codebases where making a single
by twodave 3y ago
I have been down both roads. I’ve seen unwieldy abstractions reduce a codebase down to a giant pile of edge cases, and I’ve seen codebases where making a single change to the design has required editing dozens of files. Where I’ve ended up over the years is to abstract the “big” things. The types that represent your domain. The pieces of the data layer that need to be exactly the same every time. After that, solve for large classes of problems. This may be an abstraction, a usage pattern, or just a function. Transaction management, logging, etc.
Know that if you try to wrap ANYTHING in an adapter “in case we want to swap it out later” that this almost never happens, and when it does the abstraction you came up with is probably inadequate. Transaction handling in one tech is different than another. Or logging context is handled via disposable scopes instead of as part of the log entry. For those cases, if someone isn’t already maintaining a good abstraction (like MassTransit) then it probably doesn’t exist.