Pseudocode
The purpose of design is to manage high level structural issues in your program. What will be accomplished by run time code? What will be separated out into utility classes and functions? How can you reduce dependencies in your code and still accomplish what you need to do? This is difficult to see when you're working with physical code that you are typing into your computer, tappity tappity tappity. Pseudocode is beneficial because it satisfies our primary design goal of separating high level design decisions from low level coding decisions. That may be obvious, but it's the primary goal we want during design and the Pseudocode Programming Process (PPP) meets that goal. To an extent any design process can say this however, so let's look more closely at what makes pseudocode work so well.
Traditional PPP
Pseudocode is something that all developers do anyway. At some point when writing a program, you've hit a portion that's difficult, and made a note... probably just for yourself... about what needs to happen at that point. Nothing fancy, nothing technical, just a simple note about what needs to happen in plain language (English, Spanish, Chinese, or whatever you prefer). That's pseudocode. One of the reasons that pseudocode is so beautiful is that every developer uses pseudocode whether they strictly realize it or not; even whether they've been trained in it or not; pseudocode is an emergent behavior in developers. It's something that we just do because it makes so much sense. PPP is simply about harnessing the power of that idea and putting it to work; and it has two main benefits that make pseudocode stand out as one of, if not the best tool for application design.
Programming Without Code
Developers naturally work in pseudocode when they make notes and frequently when they write comments in their code. However, PPP let's you effectively program the application without using code. If your computer could understand plain language, PPP is the set of instructions you would give it. As such, PPP is about using pseudocode to systematically cover each and every step that you need to go through in your program. This is brilliant. This means, you can basically program your entire application without worrying about coding syntax and implementation. You can work at a slightly higher level of abstraction and consider just the design of the system and it's implications. In programming code it's sometimes difficult to figure out what's going on. Because it's written in plain language, you get a much better handle on key design questions:
-
Does our application demonstrate consistent levels of abstraction?
-
Is a class handling more than one area of responsibility or more than one class?
-
If so, how can we break it up for better unity?
-
Which way does it make the most sense to code each function?
-
Is a function doing more than one thing?
-
If so, how can we split it up?
-
What is the output of each function?
-
Where is that output used?
-
Are the abstractions consistent?
-
Are there any other places this abstraction could be used to simplify the code, where we aren't currently using it?
-
What are the input parameters needed for each function?
-
Where are these coming from?
-
Do we need any more information?
-
Would this function be much more useful if we generalized it a little bit more?
-
Can we do the same job with fewer and / or simpler parameters?
-
Which variables are going to be bundled into which classes?
-
In this function?
-
In that function?
-
Should they be class data?
-
Is there a better way to organize your application?
-
Where should variables be validated, if necessary?
-
Should they be created in one place and validated by a helper function?
-
What do your custom data types need to contain?
-
Could they be built more efficiently?
-
Are they missing anything important?
These are all important design questions that you can now address in their own phase on their own terms. Furthermore, these are all much easier questions to answer when you're looking at plain language instead of code. So PPP not only gives you the ability to separate architectural questions of design from the coding process, it gives you clear, plain language answers to those questions. That's a difficult combination to beat. I find this much simpler to execute in practice than other architectural / design approaches; UML is probably the most popular technique but I find it too detailed for a high level architectural discussion and way too vague for detailed design. UML is also intricately complicated, and whole books are devoted to it, while PPP's simplicity, in my opinion, blows it out of the water. Diagramming classes and their interfaces is another popular technique and I'm such a visual learner that I do like to combine my PPP with one or two good diagrams (in the same that way I use ERDs in combination with my relational DB designs). In this sense PPP does not require an exclusive commitment; it can be part of a multi-pronged approach to design.
Pseudocode Becomes Program Comments
This is a lifesaver. No one likes to go back through their code and add in comments. It's no fun. It's difficult to figure out how much you need to explain. Are you explaining too much? Not enough? Are you explaining the wrong things? PPP eliminates this phase because PPP is about pre-commenting your code before you have even built it! So how much do you need to explain? Just as much, and in just the ways that you need to make it clear to yourself how to code it! QED.
I find that this is probably the single most effective way to understand how you write pseudocode. Each line of pseudocode that you write is going to become a comment in your finished code. If you are writing something that is too detailed for a comment, take it out. It will be the semantic names in your code that will explain those details. If you are writing a line of pseudocode, and you can't see the code which will make it happen, you need to delegate that responsibility to a lower-level function. The semantic name of the function will mimic the vocabulary used in the comment, and the lower-level function (which is now another application component that you need to write in pseudocode) will handle more specific details about how that will occur. You keep digging deeper and deeper in each function, until every portion of the application has been written in pseudocode down to the point where you can see the code you will have to write.
When you've finished writing the application in pseudocode, you can now study it. You are now looking at the program as you would have written it if you'd just started coding. This is where PPP demonstrates it's truly amazing advantages; you haven't actually written a line of code and you can start answering all those design questions we outlined above. As you answer each one, you will see ways in which this class or function is too dependent on other code. You can see a function that goes better in another class. You can consider alternative application designs. You can trace variables that you're passing all over the application and find alternatives. Any high level architectural questions can be handled right now and all you lose is some pseudocode. That's a lot easier than rewriting real code and experiencing the pain of throwing out good code which is no longer relevant to your application. Will you have to throw out good code during construction? Probably, and that's exactly why we want to fix as many design problems right here and now. It's simpler to read the pseudocode to identify design inefficiencies and you lose less work. Plus, you have all the comments you need for the entire application.
Once you've had a chance to take a crack at your pseudocode a couple times and review it until you're comfortable with your design, you're ready for construction. Construction is now simply a matter of taking each class and function, creating the declaration in formal syntax, adding braces, and commenting out all the pseudocode. You now have the skeleton of your class / function and you're ready to write some code.