When you have a good idea, there is a huge temptation to just jump right into it and get started. When the project you’re working on is tiny and guaranteed never to grow beyond that, jumping right in may even be the most effective way to get the task done. But when you have a large project to accomplish, jumping right in can be a total disaster.
Let’s say one day you decided you wanted to try to build a house. You get the house plan in your head, call up a bunch of friends, and run to your local home improvement store to get lumber, nails, shingles, windows, doors… You buy all the things that you think you’ll need to build the house and bring them to an empty plot of land with your friends to begin.
You start building. You’re not really sure exactly the layout that you decided on for the home, so as you’re framing things in, you keep having to tear down,cut, and rebuild parts of walls that are too long or too short. There was no standard wall thickness decided on so there are variations between the walls that your friends have built and your own, and because of this when it comes to nail everything into place, nothing fits together correctly. After the walls are finally put together in a hodgepodge, and nothing is square, it turns out that the drain pipes for the toilet plumbing in the bathroom are actually now in the center of the bedroom, and it will be impossible to continue building the house because the frame is too weak to support the roof.
Designing and building large scale software is similar to architecting and building a house. This was recognized by a few very smart people who discovered many useful recurring patterns they kept seeing in software and decided to document them in the book called Design Patterns: Elements of Reusable Object-Oriented Software also know as the “Gang of four” book or GOF book. Not only are there reusable patterns present in software development just like building physical structures, but to create a successful end result with fewer bugs and architectural problems you must also do a lot of work before you even begin to code.
One way or another, you need to have the design of the software down in your head and then written down and tweaked/adjusted in some medium more concrete than just your mind. For each new large project I take on, I will usually write a document describing how I see the internals of the software working together and how the design goes about solving the problem I am tasked to solve. I’ll document data structures, database layouts, and core software component interactions.
After the initial documentation of the big picture, I’ll move on to UML structure diagrams to firm up the actual classes and behavior. I’ll take this time to really think about how program should be laid out internally and make decisions about inheritance vs composition, design patterns I may want to employ, and make changes that I think will lead to the cleanest most understandable output of code when it comes time to actually start typing.
After the UML static structure, I may take some time to create UML sequence diagrams for the most complex object interactions to make sure that the design is sound and that I’m not missing anything subtle about how the calls and messages between objects will have to flow. During this time I’ll also keep tweaking the UML static structure diagram. The UML document should always stay fluid and be allowed to change throughout the development cycle.
So what is the point of all this? How is this an advantage over just figuring all of this stuff out in your head and making these determinations while you code?
It’s simple. Code is expensive and rigid. Once you have a lot of it down it is hard to change it. Changing a major system on a UML diagram involves deleting a few objects off the diagram, rearranging some others and add a few new ones. Doing this in code involves a cascading series of changes that will affect many of the classes involved in the program and a lot of time sunk into doing this multiple times throughout the initial design of the software. It is much easier to change things at a high level (thinking and documenting a design) than a low level (creating the software).
When you think ahead, by the time you get to the actual coding part of your work, you’ll already know exactly how the pieces should fit together and will have worked through most of the actual problems of making everything mesh. Coding will turn into simply describing to the computer in its own language how you need it to solve your problem. You’ll be explaining your solution to the compiler instead of trying to come up with the solution and explaining it at the same time. You’ll be happier and more efficient. You’ll get more sleep, and you might even get a bit more time with your family and friends.