Five Common Mistakes in the Early Design Stage
Creating great software requires attention to several details that can make the difference between a well-designed system in one hand, and a failure in terms of features and maintainability in another. Every software engineer has a big list of elements that are necessary for a successful project and that should be part of the work cycle no matter what happens in the team.
In this post, however, I would like to emphasize a few mistakes that are so common in this field, but that keep repeating themselves due to bad management practices. It would be great to maintain this list in mind, since this kind of information can help us make better decisions whenever we are faced with similar situations.
Solving too much of a problem
A lot of failures in software design have to do with a lack of clear focus on a particular area. For example, inexperienced programmers and managers try to work on more than they can easily accomplish. The main cause for the resulting failure is trying to solve a big problem all at once.
The reason why it is so much better to focus on a particular goal has to do with the nature of problem solving: it is easier to solve several smaller problems than finding a single solution for a big one. When human beings try to handle complex details they get overwhelmed — and this happens even with smart people. In fact, a great part of being smart is to learn how to break problems into smaller pieces that can be easily solved.
Similarly, when developers try to create a program with too many responsibilities, the result is usually less satisfying. To avoid this pitfall, try to break problems into parts that can be easily solved independently. Then, come up with a way to combine the solution so that it becomes transparent for users. As most problems in software design, there are several ways to achieve the same result. Experience can teach you the solutions that work better over time. Just become aware of the complexity of each subproblem you’re trying to solve, and try to reduce the complexity by breaking up the problem if necessary.
Solving too little of the problem
While this is far less common that the previous problem, it also happens that systems may be underpowered for the problem they aim to solve. For example, they may miss critical steps that are necessary for the execution of a process, requiring manual intervention during a workflow. When this happens, users frequently need to take additional steps to fix issues that should be covered by the application in the first place.
They main cause for this problem is a failure in the design and requirement gathering phase. It is possible that software developers didn’t have enough experience to determine the main requirements of a full solution for the problem they were trying to solve. This is a cause of much frustration for users, and it usually leads people to disregard software as always incomplete and unreliable.
The best way to fix this category of problem is to have a better understanding of the user’s needs. Many time this issue can be solved not only by adding more features to an application, but by making it more flexible, so that different users can exercise the application in the way that better match their needs. Most successful programs make a conscious effort to create flexible solutions that can be quickly adapted by users as necessary.
Designing around the user interface
While the user interface is the most visible element of a software application, it may not be the best way of analyzing and organizing the functionality of a piece of software. Unless you are working on an application that absolutely needs to have a particular interface, working first with the functionality in mind is better than blindly applying user interface elements from the beginning.
In many cases, software engineers use the interface as a focal point of feature design, this being one of the core ideas proposed by agile methodologies. They frequently forget, however, that the GUI is merely a presentation method for something of more fundamental in importance for the user. The logic and data model components contain must of the necessary parts of a program; moreover, these parts are mostly independent of any graphical interface.
Such a policy of functionality-based design may be hard to enforce if you start the project working directly on the user interface. As a result, a number of bad decisions may occur from an unnecessary focus on UI in detriment to the real functionality of the application. Just as an example, in the past it was common to have graphical applications with menus and main windows, even when that was not the best way to present functionality to users.
Not integrating properly with other systems
In most cases a system cannot be used in isolation. Even the simplest ones have to be aware of the hardware, operating system, and programming environment where they live. Similarly, software should be designed to take into consideration the degree of integration required from other systems that have already been implemented.
In a company, for example, we need to integrate with database systems, and well as other applications that provide business functionality. Web sites need to integrate with other technologies provided by the environment used such as Java, Ruby, or PHP. A smart software engineer should be able discern the best way to integrate into the environment where the program will live.
Failure in this area usually leads to systems that are underpowered because they don’t use and integrate the functionality available in the environment. Therefore this type of issue can also be viewed as a cause for the second item mentioned above. Try to make the best of existing technology in order to avoid this problem.
Not Using Common Solutions
Many engineers have trouble using established solutions for common software problems. This may come from lack of understanding of a particular platform or programming environment. In other occasions it is common to observe the familiar feeling of “not made here”, which leads many developers to recreate existing technology.
The truth is that current programming technology is too complex to avoid using libraries and other applications developed by third parties. In fact, I would characterize as a liability the urge to implement everything in a software project, for the simple reason that a single person (or team) cannot have the competency to implement all parts needed by a modern application.
The best practice is to evaluate and use libraries and frameworks that have been proven to solve all the main technical problems found during development. This has been made much easier by the emergence of open source software. A major advantage of open source is that solutions can be created for common problems and consequently shared by a whole community. A strong open source scene is a must have for most modern programming environments.
Whatever the reason for this problem, it is essential to leverage the knowledge and work available through existing solutions. Trying to reinvent the wheel is in most cases just an example of bad practices in software engineering.
Developing software requires attention to several details. I have mentioned only five of the factors that can make or break a project, depending on how well they are managed. A lot of other issues remain, but being careful about the items mentioned here can definitely help in the successful completion of complex software projects.