I teach some continuing education classes at the local University, and do presentations occasionally. These activities put me in touch with a number of people who are just getting started with programming. So, I get to hear all the usual questions one would expect. The three I hear most often are
- How did you do that?
- Can you help me find this bug?
- How do I start this project?
The first question is simple - I wrote some code... :) ok, maybe not so simple - but this is very highly dependant on what is being done, and sometimes it's just not appropriate to talk about the techniques used as this might be in violation of a contract. Whereever possible though I do try to share how I beat a problem.
The second question is a topic unto itself. Debugging code is sometimes an art form, and most developers end up with a number of especially useful techniques. I'll be writing about this in the near future.
How to start a project. This is what I want to talk about today. In particular, I want to talk about how to start a large and complex project. Simple projects are usually a case of "just doing it". But larger projects should be properly managed to ensure they are successful.
The Blueprint - A construction worker would not start building a house or office tower without a blueprint, so why should you? A programmer ALWAYS has a blueprint on hand for their coding - even if they don't have it written out. We cannot develop code unless we have an idea of what it is we want to build. So, even just the thought about what we're doing is sufficient in some cases. Well, ok, it's sufficient for simple projects.
For more complex projects trying to maintain the blueprint in your head is just asking for disaster. Especially if you are working in a team environment and everyone needs the same focus. No, it'd be better to document the blueprint. Is there a right way to do this? Well, I think the right way would be the way that works for you. Coding is not a new task, so there's some prior experience out there on this topic. There is one concept out there known as the "Software Development Life Cycle" (SDLC) that covers the states a project can be in. A Google Search reveals a number of sites out there that discuss the SDLC. So this might be a great place to start to learn out how start... Ha! I made a pun-ny!..
If we assume you're in a position where the boss comes to you and says "We need a program to do XYZ", then we can assume the "Feasibility" portion of the SDLC is done. After all, the project is feasible because we might loose our job if we don't do it. We want to save our butts don't we? So whats the next step? A mistake I see all too often is that a programmer turns around and starts writing code at this point. This will lead to failure (in terms of meeting deadlines, budgets, and expectations). We probably should get more information before we begin, so we need to ask questions. This is the "Requirements Gathering" phase of a project. This is truly where a project starts.
Gathering requirements means getting the information you need to meet the expectations. If someone says "build a web page", you should be responding with "what is the purpose of the web page?". And from there you'll need to cover everything about the web page like what graphics, template, color scheme, programming language, etc. The next step is to document all of this. By writing all this out, you can take the information back to the "customer" and prove that you know what they want AND get them to agree to what they want. This second part is CRITICAL. If you do not get their agreement, then you have opened yourself to arguments along the lines of "that's not what I wanted", which could have certain bad fallout - like not getting paid, or loosing a job/contract. Creating this document may see many iterations of "is THIS what you want? Yes, but you forgot this part". So the document may take some time to get done. DO NOT start coding until this document is done. It ends up serving as the blueprint for your application, covers your butt when someone says that's not what they asked for (to which you could reply "yep it is, you signed off on it..."), and clearly defines what is in scope of the project and what is a new requirement (which usually impacts time and budget).
I have seen this documentation process skipped, and the resulting fallout of arguments over pay and scope. I've also seen some successful projects without the documentation, but usually where the stakes are low and that usually means it's not a complex project.
So we now have a requirements document signed off, we can start coding right? Well, maybe. We still haven't defined HOW we're going to do the project, only what the project must do. There's a gray area here on if this enough info to begin coding. If the stakes are high, I would suggest not starting coding at this point. Instead, I would suggest doing a true analysis of the requirements and determining how those requirements are going to be met. This is done by way of data models, and maybe activity and class diagrams (or the full set of Unified Modeling Language diagrams). Why should we do this? In a team environment, these steps are needed so that all the programmers are on the same page. They can see how the parts are related, and tasks can be divided easily. Keep in mind though that these diagrams are not written in stone - they'll change some as code is being developed and new requirements are highlighted or gotchas found. Once you have class diagrams and/or data models, you should be able to start coding.
Most projects I have seen fail have failed for one of two reasons:
- Lack of planning
- Failure to stick to the plans
By lack of planning, I mean that the projects have gone straight from "We need to build XYZ" to coding. This results in determining the requirements on the fly. Which means that code already written sometimes has to be thrown out and redone because a new requirement has been found that made the original code useless. This means wasted effort and more time needed to complete the project. This means paying the developers involved more, or finding the tools needed for the job are not available so have to be purchased. Which means a ballooning budget. Can you see the outcome? Even if the project finishes and does what it is supposed to do (which is doubtful at this point), there will be some bad impressions left behind on the quality of work done.
But even if the project is properly planned, it can fail if the plan is not followed. If the customer keeps adding new requirements, and it's allowed, then time is diverted from the core tasks to handle the new task which leads to increased time and money. Sometimes the new requirement might directly contradict another requirement, so code has to be somehow developed to handle both (don't laugh, I've seen this happen...), and this leads to more complex code which is harder to debug so takes longer, etc... Nope, it's better to have a piece of paper that the customer/boss has signed off on, and then when a new requirement arises you negotiate with them. "That's a new requirement, so I'm not going to do it.", "This is critical, it HAS to be in there!.", "Ok, I'll do it then, but that means you have to approve more time and money - we didn't plan for this part", "Well, maybe it isn't THAT critical then...". Don't be too anal about following the original requirements, but don't be too loose either about allowing ALL changes. Be reasonable, and you'll have a very happy customer AND a controlled project.
Phew... all that and we haven't written a line of code yet. I've seen customers resistant to do such detailed planning. For them, I work within what they'd like done. I still happily work for them and take on their complex project - because I know I'm going to make more money in the long run due to scope creep (introduction of new requirements) - if I'm on a paid project. Most times if the planning is done, and stuck to, the actual coding part of the job happens very quickly with fewer bugs. So a well planned project is MUCH more likely to be on budget and on time.
Now when it comes to actually doing the coding, I would strongly suggest starting with a framework that will allow all the requirements to be met. If you are doing a web application, work out how you're going to handle security, how the pages will be built, how to communicate with the database, etc. Developing a good framework will also speed development time. But how to work out a framework is another topic.