
10 Modern Software Over-Engineering Mistakes - g4k
https://medium.com/@rdsubhas/10-modern-software-engineering-mistakes-bc67fbef4fc8#.iij9527uo
======
combatentropy
It seems to me like it has been good advice to first try to just get an app
working. Build all the features --- or at least most of them --- without
fretting about elegance. Then refactor it. If I try to plan it all out in my
head before writing anything, or if I am constantly refactoring as I go, then
I just write in circles. Anyway, my premature optimizations often are revised
out later or get in the way of other features.

It's not that I don't like elegant code. This way yields more elegant code,
and I finish faster.

\---

I also liked the part where he warns against database abstraction:

"Either you completely dumb down your data layer (and struggle with delivering
functionality), or acknowledge the database as part of your solution (e.g.
postgres geo/json features) and throw away configurability guilt. Your stack
is as much part of your solution as your code."

~~~
CodeWriter23
We used this paradigm at my second job: Make it work, Make it right, Make it
fast. I appreciate how the author challenges what it takes to be "right".

~~~
segmondy
In most enterprises, the moment you make it work, you get new projects. So get
it right the first time. I don't buy the article, you can abstract and
decouple your systems reasonable while getting it right the first time.

------
tracker1
A lot of this comes down to a few things... know when you need something and
put it off for as long as you can. Build the simplest, easiest thing to
understand and works from the get go. Some duplication is better than layers
of abstraction that provide very little value. In the end, it comes down to
experience.

There's a reason more experienced devs push back against a lot of "enterprise"
patterns being introduced early on. More often than not, they don't provide
value, make things harder to follow, and add unneeded complexity making it
harder to change later.

------
nlawalker
A few scattered thoughts on this, as someone who has recently made great
personal strides out of the overengineering/overcomplicating zone:

\- Developers who work on business applications spend a lot of time reading
about and understanding (and getting inspired by) the reusable libraries and
frameworks they use, and very little time reading about and understanding
other business applications. This is unfortunate, because the way that
developer libraries and frameworks are specified, designed and abstracted is
completely inappropriate for business applications. I think this is where the
overuse of generics and constant drive for ever more perfect abstractions come
from.

\- Metrics around unit tests also drive a lot of over-abstraction, as well as
the "shallow wrappers" pattern he mentions. Every implementation needs an
IImplementation so it's "unit testable", and because "what if we want to
change implementations?"

\- I think there's an underlying fear that code that's "too easy" or not
complex enough can't possibly be production quality, and that it's not
deserving of the time of a team of professional developers unless it's
complicated enough to need a full suite of unit tests, a dependency injection
framework, and a bunch of helper libraries.

\- Point #9 says that "people go all the way around to even slightly fit into
what's existing", but I think a lot of the drive for that comes from managers
and metrics that reward "reuse" and leveraging the work of others, as well as
the development of reusable components (nothing says "influence" like "my team
built this library that management now demands the usage of.)

\- Finally, I think the mindset that object-oriented programming and domain-
driven design puts people into, as well as a lot of cultural baggage in the
industry around big-design-up-front, should take a big portion of the blame
for a lot of overengineering of the type that the author discusses. We gotta
think about all the possibilities up front and then abstract these concepts
out of the domain into classes, and those classes need to be reusable and
testable... and once everything is grouped together it's incredibly painful to
refactor or move things around.

My personal revelation has been to start thinking a bit more functionally,
tending towards building things from the bottom up in small pieces and
assembling them without worrying about grouping them together into classes
that match the domain, and not being afraid to throw a few things away that
turned out not to be useful.

------
sidcool
This is a good article. Thanks for posting. We have been guilty of this a
number of times.

