This is a relatively well discussed topic in software development. However, I’m attempting to give it some context and resurface this topic in a different perspective. As everyone spends more time at home - you might think of building something for yourself and are now part of a one person squad to accomplish this. If your project is non-trivial and requires execution of tasks not directly related to your expertise - you are bound to face this issue. For the sake of simplicity - we will define it in the veins of
the designing of a product to be more robust or complicated than is necessary for its application.
Well, it looks like that’s the problem. It’s only you in the team. Let’s say you are the designer and the implementer - who are you accountable to ? Is there anyone who can provide you feedback ? If the answer is no here - I would say solve this immediately. What you don’t want is straying far away from your goal or vision. In an earlier blog post about
side-projects I mentioned writing down a simple objective. This is something you want to keep seeing when you try to build on features for your project. If the new idea strays away from your vision even slightly - don’t do it now. Note it down and schedule it for later.
When you are part of a one person squad - frankly there is incompetence in most of the things you do (if these are especially out of your comfort zone). It’s not your fault and recognizing this is important to at least detect this issue. Once you start running your idea by someone and getting feedback - try to notice situations where you were overly defensive when it comes to a feature. From my experience, these situations have mostly been with features I was 100% confident I got it right and these have also been the ones I have now thrown out due to over-engineering. Note these down - evaluate against your vision and determine their usefulness.
I like to think code is liability and in a one person squad this is even more true. Whose going to solve the bug in your class
MyAbstractionForAnotherAbstractionFactory ? Keep it simple - simple is good if not the best. Try to come back to the core-problems you want to solve and try to apply what you know first. You are the person whose going to maintain it - might as well write it in a way you are most familiar. Note down the issue somewhere to come back to it later.
Another approach is to read a lot of blog posts to get a sense of solutions out there ? It’s fine to get into this rabbit hole but not really. There are multiple ways to do something in software and the only way to possibly judge this correctly - is to try and see how fast you come back to it as you build things forward. If you came back to the feature to modify it within a span of days or the first coupling to the said feature - you haven’t nailed down the earlier implementation.
To solve the former situation - I tend to use state machines whenever possible. State machines are finite and you know there are only X cases to design for. It’s easy to represent - easy to reason and more easy to fix something. Follow this in code too - as far as possible try to emulate the design in your code. I frankly don’t like documentation much - but so far designing on paper before implementation has been extremely helpful. Write everything down - make a reference of whatever you read and apply it in your project. Hold a retrospective for yourself after you’ve gone through a feature. Weigh what you used and if the decisions you made were correct or not.
Over-engineering is going to happen when you are by yourself. The trick is to detect this as early as possible. Early successes in a project is highly valuable and necessary to go the final stretch. Get feedback early on and learn from your mistakes and know that you’re not going to be right in many situations. Incompetence will exist in areas outside your expertise - being a continuous learner here is bound to get you the results you want.