A lot of programmers tend to over engineer their software solutions.
In the course of my consulting, I have reviewed many applications from many companies. In many cases I find a lot of areas where the software was just too complex. The reasons for this are varied, but seem to be centered around a few main areas: inappropriate use of design patterns, the “not invented here” syndrome, and building a Cadillac when a Chevy would do the job. You can solve these issues in many ways. All it takes is a little bit of re-thinking on how you build software. This article offers guidance on some things you can do to simplify your software development process
When designing a solution to a problem, you should strive to make things as flexible as possible. However, too much flexibility can lead to hard-to-understand code. Instead, consider writing a class that just solves the problem in the simplest manner (the Chevy approach). Make your class extensible by letting others inherit from it. Make your methods virtual so someone can come back later and re-use part of your code, and add on more flexibility and complexity later if needed (the Cadillac). After all, this is what OOP is all about-the ability to extend and override as new requirements come up in the future. Again, just write the minimum code necessary to get the job done. Nothing more. Nothing less.
When designing your classes, use good descriptive names for the class itself, the methods, and the properties. A class that is self-describing is, by definition, simple and easy to use. Try to avoid jargon and abbreviations. Use full, long words to get the point across of what the method or property represents.
Add comments where your code might be a little obscure. However, if the comments take more lines than the code, then you might want to look at how you can make the method simpler. Maybe you can refactor the code into another self-describing method, or use more descriptive variable names.
Design Patterns
Yes, there are many design patterns out there. Most of them are really good. However, you will find many implementations that are just way too complicated and are overkill for most situations. You need to try to find some middle ground that will work for just the solution you need right now. Don’t try to create the most robust solution to a problem that might not even exist right now. It is better to take a minimalist approach, use a basic design pattern, and get a product out than to spend way too much time trying to implement a pattern that in the end does nothing to solve the business problem you are working on.
Don’t Reinvent the Wheel
The best thing about programmers is they like to program. The worst thing about programmers is they like to program. Programming is fun and that is why we do this job. However, don't lose sight that your job is to support the business you work for. Your real job is to create an application that makes your company money. If that means that you need to re-use someone else’s code, then do that. You just can’t get hung up on the “not invented here” syndrome. If you do, then you are not doing your job for your company.
“The best thing about programmers is they like to program. The worst thing about programmers is they like to program.”
There is no reason for a business application programmer to reinvent every solution. A business programmer’s number one job should be to support the business. Period. Your job is not to just have fun programming. Yes, that would be great, but if the company you work for needs a program to make money, then it is your job to get that program done as quickly and efficiently as possible. If you don’t do this, and your company loses business because of the lack of software, you might just find yourself out of a job!
Put a Wrapper around Microsoft
Don’t get me wrong. I really like Microsoft, and I love using their tools. However, you need to be careful when you choose to use a new technology as this can lead to code that might not work in the future. Consider what happened between .NET 1.x and 2.0. Many things that they told you to use went away. I’ve seen this time and time again with Microsoft in the past. Look at how many data access technologies they have had us use over the last 15 years!
In my seminars I always tell people to put a wrapper around Microsoft. This means that I will take LINQ to SQL, the Entity Framework, LINQ to XML, the ConfigurationManager class, and other technologies and call them from my own classes and methods. By wrapping these technologies in my own classes I only need to change the code in one place when Microsoft decides to change these technologies. This ensures that I can keep all of my other application code consistent, and I just use a different technology under the hood.
Team Programming
I am a big fan of code reviews and team programming. If I can’t explain my code to someone else in a minute or two, then I have made the code too complex. Every day you should review your code with a co-worker to make sure that it is not too complex. If you work alone, then grab a friend, your spouse, or your dog and explain the code to them. Sometimes just talking about your code out loud to someone who does not even understand programming can help you identify potential problems.
Since I teach many seminars and write many articles and books, I know that my code will always be held up to a microscope. I strive very hard to make my code readable and understandable to a wide range of programmers. So as I write code, I always think about how that code looks to someone who is just a beginner. If a beginner can understand my variable names, my method names, and my logic, then I know an experienced programmer will too. Think about your code in the same light, and that may help you write simpler, easier-to-understand code.
“…write the minimum code necessary to get the job done. Nothing more. Nothing less.”
“Right” Engineering
If you look at two pieces of code, you can tell immediately the code written by a beginner programmer and the code written by an experienced programmer. The beginner will probably have under engineered the code. However, an experienced programmer will most likely have way too much code (over engineering). Under engineering code is when someone does not put enough thought into solving a problem.
“If I can’t explain my code to someone else in a minute or two, then I have made the code too complex.”
Consider the code in Listing 1 that checks to see if a file exists. You can see that this person did not put enough thought into the reusability of this code, nor the exception handling. Now, if you look at code to solve the same problem written by a programmer who tends to over engineer code, you might use the method in Listing 2.
Yes, the code in Listing 2 is very good and solves almost every conceivable problem that could happen by attempting to check to see if a file exists or not, but is this the code that was needed to solve the business problem? Most likely, the code could have just simply had a single catch block that included the file name and the error message returned from .NET and that would have been sufficient. Someone took too much time to create this over-engineered method and to test it. That time could have been better spent working on the business problem.
Summary
Having robust, flexible, reusable software is a great goal. However, that goal does not do any good if you don’t deliver a product that helps your business. Start out by developing software that does just what you need and nothing more. Make that code extensible so you may add onto it in the future. Use simple design patterns and write your code like you will be presenting it in front of a large group of your peers. Follow these techniques and you should find that your code will be simple and “right” engineered.