How do you know when you're over engineering a problem?

Started by
3 comments, last by Guy Fleegman 5 years, 5 months ago

I just started a new position as a programmer and I'm trying to balance doing things well and in a timely manner. The old code bases where I work now are a disaster and I want to at least set a good example going forward. how can I know when I'm over engineering a problem? I read a lot about design patterns and coding principles, but I feel like when I actually code I take forever due to wanting to implement something well and clean. Any advice?

Advertisement

Over-engineering can be a problem, and a large time-zapper. Sometimes, for juniors especially, it can be hard to tell if you are over-engineering something. Especially if you've no idea how else a particular problem _could be_ approached.

That being said, I'm assuming you are following a agile/scrum methodology where you take on stories that have points assigned to them relative to the effort the story owner thinks it will take, so, imagine this scenario


Story Description: 

We need to leverage a DB to store historical 
metering data for one our switches so that we can later generate 
a report to send to Accounts Recievable. 

**Success Criteria**

*Create the tables on our pre-exisiting Database cluster
*Write out the code to insert the Metering data from the tool to the new DB tables
*Generate xlsx/csv/whatev Report

**2 POINTS

Give that story a look over, and ask yourself, "What is this asking of me?" Is this story asking you to write an agnostic DB layer to handle the lifetime of DB sessions across multiple applications as a library? No. Is it asking you to write a methods that tallies the 95th percentiles of the interface bandwidth metrics that your client is consuming? No. 

What the story asks for is precisely what it asks for. Always do what the story says. Deliver, deliver, deliver. If necessary, clarify with the story owner, or bring up ideas that you have that can bring some of that aforementioned functionality into the fold as separate stories/feature buildouts to your senior engineers, or to the rest of your team 

The burden of elaboration should always lie with the story owner, not the developer in cases where the story owner expected a feature not initially requested.  

7 hours ago, mrpeed said:

The old code bases where I work now are a disaster

That's normal to think about code not written by you. However, it is generally safe to assume its authors were at least as sane and smart as you are.

They just had different ideas, different backgrounds, different experiences, and different preferences from you. As a result they don't write code like you do, and thus it looks like total alien to you, which is very easy to confuse with "it's a mess".

In other words, in my experience, it is generally the case that you haven't grown into ideas and conventions of that codebase. It has logic and structure, you just don't see it yet.

7 hours ago, mrpeed said:

I want to at least set a good example going forward

Sounds like a good idea. The problem is however, what does that mean?

One tempting direction is to make a new start in some way, add 'your' corner somewhere, where code works according to your ideas. It's tempting, because such code feels like "home" to you, you wrote everything, so you know it inside out. It's safe to assume that your pre-decessors felt like that when they wrote the code you now have (remember, they were sane programmers like you, they had good intentions like you). So, how would you think the programmer after you will feel about your code?

A more difficult direction is to learn how that code base actually does its job. What structure and logic does it use, how are variables and function named, etc. Become adjusted to the ideas and practices of the previous programmers. Try to be the previous programmer. You will find sanity and structure in that program once you adjusted enough. Then follow that style when you make changes. The next programmer will not curse you for adding yet another new piece of code in a different style.

The biggest problem here is that understanding and adapting already existing code is a completely different skill from writing code from scratch. The latter is what everybody calls "learning to program", while in reality, the former is another very important skill (everybody has an existing code base that needs to be changed), yet very few learn how to do it.

 

The trick that worked for me is to just start documenting any code and variables/constants that you think you understand but has no documentation of its own currently (and given the average code base, it's a safe bet that such code exists in your code base). Don't make changes, just learn what is there, documenting your findings for you and your successors (once they understand your style). Reverse engineering code is something you should avoid (it's a high-risk activity, since we tend to miss crucial hidden ideas in foreign code that we read), so make sure it's not needed to do that work again.

After doing that for a while you'll start to see patterns in names, functions, and other structures. Slowly you start to understand what the code is doing and how. At that point you may want to carefully start with making changes, as you are in a position where you can understand it will work as intended.

 

8 hours ago, mrpeed said:

how can I know when I'm over engineering a problem?

When you're solving a problem that does not exist today. It's not a black/white thing though, there is a whole lot grey area in there between the extremes. I mostly follow the rule of "make the simplest solution that works for todays problems". 'today' is also not black/white, if extension X on todays problem is a safe bet, it's usually fruitful to make that extension not impossible in your solution (ie, don't build it, but do make sure that extension X wont cause the current solution to be fully rewritten.)

8 hours ago, mrpeed said:

I read a lot about design patterns and coding principles, but I feel like when I actually code I take forever due to wanting to implement something well and clean. Any advice?

Yep, high-level ideas are quick and simple, code is terribly hard and detailed. The reason for that is because you're writing recipes how to deal with complicated concepts relevant to human life to a non-sentient device, which is very good at taking orders but can't count further than 1.

The trouble is, code is even the simple part, it's a solution, like "42". The really hard part is explaining how you reached that solution from the complicated human concepts  to fellow human beings, so they can understand your reasoning, and find the point where a change has to be made due to a change in the set of human concepts that has to be dealt with, ie "what was the question to that answer, and how is 42 the solution?".

If the code you're trying to figure out is working, don't rewrite it simply because it doesn't follow your logic. If the code is poorly documented, figure out how it works (because it obviously does) and add your own comments as to how it accomplishes the task for future reference (and your sanity). All you should be concerned with is that your own coding contributions are clearly, concisely and consistently documented for the next person after you.

A coworker might be impressed by how you reduced the lines of code in a function, you might be impressed by how you rewrote a bunch code to fit your programming conventions, but neither of those things will impress your boss. In fact, they'd probably think that was a waste of company time and money.

You might be a bit of a perfectionist (I know I am), but you have to pick your battles wisely. Be a perfectionist at documenting and testing your own code. And always remember that there is no right or wrong way to code. Well documented code is good code.

This topic is closed to new replies.

Advertisement