Up until this point, the Bitwise Operator column has provided an introduction to writing software on the MacOS. While this would continue to be a valuable journey, there are 3 important reasons to change the content: the effort to create and maintain the library is prohibitive, there is enough controversy regarding the lifetime of the platform, and there are many more topics of general interest to developers.
To this end, I'm changing the content of the column to include general topics relating to software development and maintenance. If you are anxiously interested in learning to program for the MacOS, I'd strongly recommend that you purchase and read some of the excellent Mac programming primers and visit the Mac related discussion areas on UseNet and IRC (as described in my first column).
"Wait a minute," you say. "I'm a damned good programmer!" And most people for whom programming is incidental to their job or for whom it is a hobby, indeed are good programmers. But once the project grows beyond one or two people, the source code spans several projects and libraries, and/or you are targetting for multiple platforms, it becomes easy to waste time in unnecessary or avoidable situations.
Each of the upcoming columns will address a different aspect of software development: design techniques, project structuring, and tools for writing, debugging, and managing your code. Some of them you may be familiar with, others you may or may not have heard of in passing. Regardless, the focus will be on filling in those gaps that even a traditional CS degree will leave you with.
The first type of programmer gets off to a fast start, and generates alot of code very quickly. He is able to dive into 3rd party code and libraries, and make use of them quickly with little fuss. He sketches out the program structure in broad strokes, making some basic assumptions about the intended design so that the code can continue to flow.
As the project continues to grow, the programmer needs to address issues that were previously postponed. Early assumptions often become hard coded limitations of the engine. The application is structured incrementally, and may not be very extensible or even efficient, although it works adequately. Common or repetitive tasks are often implemented in several locations, so continued development and maintanence becomes increasingly difficult.
Later in the development cycle, user feedback may indicate a change in direction to which the developer must modify the architecture. Poor design may make portions of the code difficult to extend without significant retooling, which means redundant work. In effect, such a programmer gets a good start on the project, which is fine for small or one-off products, but which will only hamper an extended project or large source base.
The second type of programmer (of which I am) spends time planning the project, so that it's implemented "right" from the beginning. He lays the framework for the project with a flexible infrastructure, handy utility routines, and extensible handlers. He'd rather spend time preparing for the major tasks than diving in, so that the code doesn't need to reimplemented from the ground up for later enhancements.
The programmer likes to pay attention to the details, and will spend a fair amount of time optimizing what he sees as the most important parts of the program. Rather than just drop-in third party code or libraries, he insists on being familiar with the mechanism; he may even reimplement some of the core, or at least wrap his own handlers around the API.
The biggest pitfall these programmers face is procrastinating the coding process too long. They often diddle with design sheets, utility libraries, or optimizing the core engine, and postpone the more significant portion of the engine until everything is "just perfect". While infrastructure is important, so is actually getting the project to work.
While some coders and software engineers fall into the extremes of these stereotypes, most fall somewhere in between. Despite this, everyone should be wary of falling into either "trap" -- and what that requires is focus. Coders in the first group must be willing to step back and look at the big picture. Bootstrapping some functionality is fine, but you should focus on some goals -- keep the code modularized, the APIs clean, and always leave room for extensibility (reference constants, accessor function, opaque data types).
Engineers in the second need to roll up their sleeves early in the process. Writing your plan on paper is fine, as long as you recognize two things: even the best plans may need to be revised or discarded in the future, and spending too much time on too little code (no matter how essential it is or how often it's invoked) affects the whole project. Save the 5% speed gains for version 1.1, and focus on making something functional. Frameworks and early development versions are much more interesting to demo than a handful of really optimized blitter functions written in assembler. (Use the "mom test" -- which one would she be more impressed with?)
In the end, it's a matter of not drifting to one extreme or the other, but walking carefully in between. If it takes weeks to plan and organize the project, it's easy to fall behind schedule while not making observable progress. If the first pass of code seems to work, but it's not well organized or debugged, then it becomes difficult to complete and maintain the project.
Matt Slot, Bitwise Operator