I’m in the middle of a large effort to both deploy new functionality and refactor old code in the Intranet I built for my employer. I’ve got close to 700,000 lines of code to review and as I get into the older code I feel as if I’m reading the rings of a large tree and getting closer to the center with each day.
It seems every day I learn something new. I can write PHP code, but as any programmer knows there’s always a half-dozen ways to skin the same programmatic cat. Most get the job done but some ways are better than others. As I learn better ways of doing things I implement those methods in new code, but some are worth going back through the old stuff for a retrofit.
As I peruse my old code I remember my rationale for the methods I used. It’s not so much a, “Why did I DO that?” kind of thing, but more of a reminder that sometimes it’s worth taking the time to ask, “Is there a better approach?”
As a general rule I put comments inline whenever something isn’t immediately obvious. This helps tremendously when reviewing code I wrote one or two or three years later. I also put comments next to variables or functions that are defined elsewhere, indicating where to look for the parent code. That has been a big help as well.
As I code in the present, it’s valuable to remember to think of the future. You probably don’t have the programming chops today that you’ll have in a few years, and that’s okay. No one does. Do the best you can with the skills you have (or can look up) today. But code in a way that makes it easy to go back and clean things up when you get the chance.
Yesterday I attended the Portland session of PHP|Architect‘s Codeworks 2010 PHP developers conference. Unlike the previous year’s event which lasted two days, this year’s one day event was a little lighter on actual how-to’s and instead focused more on concepts and inspiration. As Marco Tabini put it, “You should come away from this conference with more questions than you had when you arrived.”
Despite the reduction of how-to substance, I still came away with some valuable insights and — thank you, Marco — inspirations. As was the case when I attended Codeworks 2009 in San Francisco this same time last year, the bulk of what I gained was a needed push toward a more formal development life-cycle. I’m a one-man development shop so I bypass or skip several processes that most multi-member development teams rely on, such as scripted deployment, code analysis, and unit testing.
One of the questions I raised during D. Keith Casey’s session on “Unit Testing Strategies” was, “As any writer knows, it’s not a good idea to proofread or edit their own work. Does the same apply to programmers testing their own code?”
Keith felt the same principle applied. It’s always a good idea to have someone test the code other than the developer that wrote it. However, what about one-man teams like myself, “Test-Driven Development (TDD) works great for that because you write your tests before you write code.” It makes you a tester that writes code rather than a coder that tests.
Compared to the other sessions by Keith Casey and Cal Evans, I felt like Marco’s two sessions, “Learn to Love the Front End” and “Object-Oriented Programming in PHP 5.3″ were more cerebral and theoretical. Marco covered two topics that many people take for granted with an insight that reminded me of a veteran college professor. The depth of Marco’s knowledge and understanding of computer science was apparent. His explanation of the progression from commodity products to the ‘experience’ end of the product spectrum was brilliant (malted barley vs. sharing a pint with friends at your local brewpub). His analogy was even more poignant considering he doesn’t drink.
Cal’s coverage of “API’s from the Ground Up” over-focused on REST-ish ‘verbs’ and response codes — a mere slice of the API pie — yet didn’t even touch on the why of creating an API. He never answered the unspoken question, “Why would I write an API?” It almost felt like he threw together the presentation at the last minute on the topic without really thinking the whole thing through. I understand that these sessions were not supposed to be end-all, beat-all training programs, but if you’re going to give your audience only a thin slice of information on a topic, at least spend 30 seconds telling them where that slice resides within the big picture. I did learn some things about APIs, but wanted more. To his credit, however, Cal has the kind of personality and presentation style that makes it an enjoyable experience. He could read the phone book aloud and make it fun.
Keith Casey’s presentation on scalability was insightful. Unlike Cal’s session on APIs, Keith let the audience know why scalability mattered. He then gave specific areas to look for bottle necks and discussed broad methods — and some specifics — used to correct them. The session was intriguing and stayed true to their goal: motivate us to ask more questions and dig deeper on the subject.
Cal’s second session of the conference, and the last one of the event, “Five Tools Every PHP Developer Should Love” did in fact cover five tools but the usefulness of some is debatable. phing is probably the most useful tool to me, as it helps automate many other tools and tie them together, enabling the development team to create formal deployment processes. That is something I don’t follow, being a lone coder, but I intend to change that.
I suppose that’s the nature of these conferences. Their value can be measured in the worth of a single tidbit or fragment of inspiration. After attending two year’s worth of Codeworks conferences I can wholeheartedly say they are worth the time and expense to attend, even if it’s in a city far away. Not every session’s topic will apply to every attendee, but it’s not feasible to expect it to. Also, the presenters have day jobs writing code and managing teams, so their presentations tend to be more about the content than the polish. I actually think that’s a good thing.

daycamp4developers.com
On Saturday I participated in a webinar called “Day Camp 4 Developers“, hosted by Cal Evans and sponsored by AutoMD, Microsoft, VACO, Ascendant Staffing, EICC, and PHP|Architect. Thank you to the sponsors for making the event possible and to Cal Evans for organizing and hosting it. Great job!
This webinar included presentations on soft skills needed by developers rather than code-centric how-tos. The bang-for-the-buck on this event made it worth a great deal more than the actual cost of $35, and was a great way to spend a few hours on a Saturday.
Presentations included “Open Source Your Career” by Lorna Jane Mitchell, “Technical Writing 101″ by Elizabeth Naramore, “Rocking Your Resume” by Scott Gordon, “Actively Managing Your Career” by Brian Prince, and concluded with “So You Want to be an Architect?” by Josh Holmes.
The event was presented using GoToMeeting’s Webinar capabilities and other than a minor technical glitch during the lunch break it went off without a hitch. What I found fascinating was that every participant, both presenter and attendee, was in a different geographical location. The entire thing was conducted over the Internet and no travel expense or time was involved. I still gained the benefit of the talks without the hassle, time, and cost of traveling to an in-person conference. Granted, I don’t get the benefit of off-line conversations in the hallway and lunch room or bar afterward with the speakers and other attendees, but considering the very low cost it was still a very worthwhile experience.
November 7th, 2010 in
General,
Training |
No Comments
It’s easy to develop web pages in a vacuum. To build and build is fun, but how often do web developers stop and listen? Creating wonderful web sites without spending an adequate amount of time listening to users’ needs, both before the build and after it’s running live, sounds the same as one hand clapping.
Ask any developer and they’ll tell you where their passion lies. Whether it’s creating cool graphic designs, awesome flash videos, or writing killer code, there is something about their career that excites them. How often do they say, “Interfacing with clients is the reason I get out of bed every morning!” ???
I’m not saying us web developers and designers are anti-social (although that’s true for some of us). What I’m saying is we tend to get caught up in the creation and forget to listen to the reason why we’re creating it: the users.
Before a project begins, the users will be more than happy to tell you what they want. They may not have any idea how it should best take form, but they’re full of opinions on the idea. But what about after you’ve created it? Do you follow up and find out how it’s going?
In the beginning, focus groups and guided function interviews provide valuable insight into what the web site is supposed to do, and through that you can glean the best way it will do it. Once it’s built, exit interviews with users as they sit down at their web browser and use the site are equally important. It’s nearly impossible to please your client 100% accurately the first time. You’ll almost always find tweaks and changes that make it even better after it’s up and running.
Another critical piece of information can be mined from web site log files. Analyzers abound that crunch the sometimes massive log files and turn them into valuable metrics that actually mean something. I use a somewhat old but rather powerful log analyzer called Analog. Using it, I can determine what pages and sections of my sites are most and least popular, as well as dozens of other metrics. Some of the most important involve web browsers. Which ones are most popular? Which ones are on the rise? Are smart phone users visiting your site on an increasing basis (they are almost across the board)? What operating systems are in use?
These stats may or may not help you once the site is built, but they can offer some valuable insight that helps you make potentially big decisions on your next project.
The old saying goes something like this: “Those who can, do. Those who can’t, teach.”
I beg to differ. I think it should be: “Those who can, do. Those who can really well, teach.” And I’m thankful for it. Teaching is not an easy thing to do, although to some it comes naturally. In my career, I’ve taken regular college-level courses in various technical topics and programming languages, but haven’t really gotten into that whole “attend conferences and seminars” thing until recently. Last year I attended the PHP Code-Works conference in San Francisco and will be attending this year’s event in November, held in Portland, Oregon. I also signed up for Day Camp 4 Developers, put on by Cal Evans, whom I met in SF last year.

Day Camp 4 Developers is an on-line training session in three segments: Career Management, Technical Writing, and Resumes. I encourage other PHP developers to sign up.
I’ve written a lot of documentation in my career, so much that sometimes I feel more like a technical writer than a programmer. Documenting your work is one of the foundational principles of software development. Keeping it updated is almost more work than maintaining the code itself, and equally tedious. The great irony — sadness, actually — is that it seldom gets read by users.
There have definitely been times when I wrote documentation simply so I could say that I had done so. My supervisors listed it as a project requirement, but everyone on the team knew the document wouldn’t be viewed by human eyes other than my own.
Is documentation still worth the effort? I believe so. Sometimes the benefit of documenting your work isn’t in the reading but in the writing. There have been many times when I have discovered a logic flaw in my code by writing about it in the end-user documentation. It also forces me to think about the application from the user’s perspective. Does this functionality make sense? Could it be more efficient? Is this interface intuitive or needlessly complex?
For Internal Use Only
Not all documentation is for end-users only. Early in my career I learned the difference between an Internal Functional Specification and an External Functional Specification. The External Spec is written with the end-users in mind. It explaines how to use the application but does not go into any details about how it does so. Turn the wheel left to make the car go left, press the brake pedal to make it slow down and stop, etc. The Internal Spec gets under the hood and explains how the car moves when input is provided by the user into the steering wheel.
I was a lead developer on a web project for a national credit union. The web site let their users conduct transactions on-line. The entire project’s internal specifications were fully documented by a single man, the project leader, prior to a single developer being brought on board. This guy thought of absolutely everything. When I began writing code, I never had to ask a single question during the project, everything was already in the book. It was almost creepy. How he was able to think of every detail the programming team would need and document it was a feat I’ll never truly understand. He was like the Rain Man of project architects. But that document gave me what I needed to stay on task and get the thing built on schedule.
I tend to write internal specs in different phases. Basic functionality and data structures are sketched out in preliminary form as the planning phase moves forward. When I delve into the details of specific sections and really flesh out functionality, I update the internal spec accordingly. It’s rare that I’ll make substantive changes to the document once coding begins but it’s not uncommon for tweaks to be made to data structures during the development phase so I’ll update the internal spec accordingly.
I write the external specification — end-user documentation — once the project is developed. This often happens simultaneously with the testing phase, with summary documentation provided before testing begins to give beta users basic usage instructions. Testing can often help the documentation process by giving me insight into how users respond most effectively to instruction.
It’s not uncommon for me to be the only reader of the internal spec. Since I’m the sole developer on 90%+ of the projects I work on, I seldom worry about fancy formatting and just get the core of the content in there in basic form. External specs seldom get read by end-users in their entirety. I have found summary “quick start” guides to be far more effective. Give the user the skinny on how to get started right away and they’ll love you for it. Make the unabridged versions available for reference but don’t expect it to be cracked open by very many users. That often comes in handy the most when you’re out of town and unavailable to answer questions in person, which can be invaluable.
No matter how you slice it, documentation — internal and external — is a valuable effort. Just don’t expect it to be on Oprah’s book club list.
Whether you’re in Computer Science or a related program in college, a budding programmer in high school, or a veteran in the field that’s been around since COBOL was the Hottest New Thing, everyone has their own way of doing things and their own, often vocal, opinion about the way things ought to be.
What’s funny is the two are seldom the same.
Does that make us hypocrites? Do we spout ideologies about the way things ought to be while doing something completely different in practice? Or are we so vehement about the Way Things Should Be Done because we’re actually very much aware of our own failings to meet those standards and we’re subconsciously trying to pep-rally ourselves into line?
I’m a bit more practical about the whole mess. I’m very well aware of how things are supposed to be, and I’m also unafraid to admit it when my own practices are a bit less kosher.
Q: Do you use source code control?
A: Yes, but not until recently. I use SVN integrated with Eclipse within OS X, but not because I feel the need to. I do it because everyone says that’s what you’re supposed to do. My development team has three people on it: me, myself, and I. In my programming career (more than two decades), when flying solo on development projects — which has been at least 90% of the time — I can count on one hand the number of times source code control and/or version control would have saved my bacon. When working on teams of more than one individual I see it as mandatory, one of the first tools that should be put into place on the project. But working by yourself? In my experience, not so much. I rely on Time Machine backups (sorry, Windows folks) which back up my code once every hour, and when posting new files to my staging or live servers I save and archive the previous versions before dropping in the new stuff. Basically I have multiple layers of redundancy and versions that I can revert to. Doing side-by-side comparisons between different versions of files, an admittedly handy feature of most version control systems, simply has not been a necessity for me.
I actually got chastised somewhat harshly by a presenter at a PHP developers conference when I confessed that not only did I not use source control (at the time) but that I didn’t feel it was necessary for a single developer in my situation. I’m not going to name names but the presenter came very close to crossing the boundary of professionalism and courtesy in his remarks. However, I agree with his opinion despite the delivery (maybe that’s the approach I needed most) and have since implemented source control in my own practice.
Q: Do you use a formal deployment tool or proces?
A: No. It’s extremely rare that I have to deploy more than one task order at a time where maintaining trunks and branches matters, and I’ve never had to deploy to more than one live server at a time. Also, my development environment consists of a development machine (my Macbook Pro running XAMPP), a test machine that test users can access, and a live server. If I were working on a team with multiple developers, multiple servers, or had deployments that overlapped, a formal deployment process or tool would definitely be appropriate.
Q: Do you deploy code on a schedule or ad-hoc?
A: I work on two types of tasks: ad-hoc feature changes and bug fixes, and new feature projects. Because I’m a development team of one, I tend to deploy ad-hoc feature changes and bug fixes individually as soon as they’ve passed muster on my test/staging server. For feature enhancements and other large projects, I schedule their deployments in advance so that I can alert users to any potential server outages or training opportunities, but I don’t follow a schedule dictated by the calender per se (e.g., “Deployment Fridays”, etc.)
Q: Do you use an IDE or a text editor when writing code?
A: (On my Mac) I use Eclipse with SVN integration for PHP development, and Coda by Panic Software for static HTML and other light-duty PHP coding. I create graphics by hand in Macromedia Fireworks, and edit images using Adobe Photoshop and ImageReady. I used to rely on Dreamweaver back when I wrote a lot of ColdFusion under Windows XP, but I found it to be bloated and slow for the Mac. For basic text editing I use TextWrangler.
Q: Are you a procedural programmer or do you follow an object-oriented methodology?
A: Yes. Sorry for the confusing answer, but I utilize both approaches whenever each one is most appropriate to the task at hand. I have noticed that people tend to fall into one or the other camp, often by rote and without the concept that the other method might be just as useful, or more so, in certain circumstances. I’m all for code re-use, loose coupling, etc. There are many situations where taking an object-oriented approach is overkill and procedural methods are the most efficient. There are also times when doing things procedurally could rather bluntly be considered pure laziness — taking an object-oriented approach is the most appropriate for the circumstances. If you looked at most of my code you’d see a blended approach, all living happily together within the same applications.
Q: Are you an operating system zealot?
A: Many people I work with tease me about being pro-Mac and Apple (most of the users I support as IT Manager use Windows XP). I started out in DOS, then moved to Windows 3.x and have used Microsoft operating systems all the way up to today’s Windows 7 suite. In between I used OS/2 Warp v3 and 4, then spent several years using Linux distros, including Red Hat, Mandrake, SUSE, and now Ubuntu. My main workhorse operating system is OS X Snow Leopard, however. Of all the operating systems available to me today, I find OS X to be the most refined, stable, and well thought-out. If Macs were not available to me, I’d use Ubuntu 10.x, followed in preference by Windows 7. I’m not a zealot, but I do have fairly strong opinions and observations about which products are best suited to different situations, and those opinions are based not on blind zealotry and brand loyalty, but on the pros and cons and strengths and weaknesses of the operating systems currently available. Each is best suited to different applications and user types.
In PHP, parameters can arrive into a page from multiple sources: GET, POST, SESSION variables, cookies, etc. There are often situations where an expected parameter can arrive from more than one of these variable scopes. Rather than write conditional code to check each possible scope for the incoming variable, I wrote a piggy-back method called captureArg() on top of an open-source input filter class (called “$clean” in the examples below) I found on the Net (there are numerous excellent examples; pick one).
Let’s say I have a form action script that processes a user’s form submission, grabs values from a database based on criteria found in the incoming fields, and returns the result set. The script is expecting a field called ‘sk’ (for search keyword), and it may arrive from either the GET or POST scope, but may also have a favorite value stored as a cookie or even a session variable. Rather than check all four, I call captureArg() like this:
require_once 'class.input_filter.php';
$clean = new input_filter();
$tSelectionKeyword = $clean->captureArg('sk', 'VAR');
In this example, I call the captureArg() method within the input_filter class, and pass it the name of the parameter and it’s expected type. The function is smart enough to use ‘VAR’, ‘TEXT’, ‘TXT’, or ‘CHAR’ interchangeably. I can also pass an optional default value as the third method parameter in case the variable ‘sk’ doesn’t exist in any of the known scopes. In this example, I’m leaving it up to the method to set a default value.
At this point, I can use captureArg() to collect just about any incoming parameter using a single line of code, without having to guess what variable scope it exists within. Here are some examples:
$tUserID = $clean->captureArg('user_id'); // Integer type with a default value of zero
$tPostDate = $clean->captureArg('post_date', 'DATE', '1980-01-01', 'Y-m-d');
// Date type, default value, and format
$tOrderTotal = $clean->captureArg('order_total', 'FLOAT', '0.0');
Want to see how the code works? As you can see, it can be expanded to include multiple variable types, and even additional variable scopes pretty easily.
function captureArg($pInval = '', $pType = 'INT', $pDefaultValue = '0', $pDateFormat='Y-m-d') {
if ( isset($HTTP_SESSION_VARS[$pInval])) {
$tRetVal = $this->process($HTTP_SESSION_VARS[$pInval]);
} else if ( isset($_POST[$pInval]) ) {
$tRetVal = $this->process($_POST[$pInval]);
} else if ( isset($_GET[$pInval]) ) {
$tRetVal = $this->process($_GET[$pInval]);
} else {
$tRetVal = $pDefaultValue;
}
$tType = strtoupper($pType);
switch ($tType) {
case 'INT':
$tRetVal = intval($tRetVal);
break;
case 'FLOAT':
$tRetVal = floatval($tRetVal);
break;
case ($tType == 'VAR' || $tType == 'TEXT' || $tType == 'TXT' || $tType == 'CHAR'):
$tRetVal = trim($tRetVal);
break;
case 'DATE':
$tRetVal = date($pDateFormat, strtotime(trim($tRetVal)));
break;
default:
$tRetVal = trim($tRetVal);
}
return $tRetVal;
}
You may notice a call to a local method called $this->process(). The process() method is included in the input filter class I obtained and performs several input filtering techniques, including the removal of HTML tags, etc.
If you want to get something done, do it. When writing PHP, if I need to output something to the screen or save a record in the database, I write code that performs that function. But something happened in recent weeks that changed my approach to this situation.
Instead of writing code to perform the operation, I began writing functions that perform the operation. I would then insert calls to those functions. Long-in-the-tooth programmers that read this are probably thinking “Duh!” but there’s something subtle about this.
Even though I’ve been writing code since the mid 80′s, I’ve always had a ‘use whatever approach best fits the current need’ way of doing it. If it makes sense to write a function, that’s what I do. If it makes sense to build a class, that’s what I do. If it makes sense to write the functionality I need in-line with the main body of code, that’s what I do. I don’t have a default way of doing things like many developers do (OOP, anyone?)
The way my mind works is to ask, “Will this functionality be needed elsewhere? If so, write a function. Does this functionality need to encapsulate both code and data? If so, write a class.” This time, however, I began writing functions right away and didn’t specifically ask myself those questions (I already created the necessary classes for the project). Then something remarkable happened.
As I began coding the different versions of functionality that would be available to different levels of users (easy and advanced, create and edit, etc.) I found I had created a library of handy drop-in functions that dramatically increased my programming productivity. It seemed counter-intuitive at the time, but creating functions took slightly more time up front but dramatically reduced the amount of coding required soon after.
Instead of building results, I wrote functions that produced those results. Whenever I needed that result, I’d call the function instead. Again, this probably seems old-hat to many developers, but what’s different is that I took this approach by default right from the start rather than making that choice as I went along.
It was subtle but profound.
It’s impossible to please everyone. As a developer, it’s my job to please as many of my users as I can. This means creating web apps that are pleasing to look at, easy to use by both newbies and power-users, and easy to figure out for first-time visitors.
This is an impossibility, a chasing after the wind. It’s easier to play pool with a rope.
I maintain both our public web site and our rather inclusive Intranet, both of which I created from scratch. Public web sites tend to follow a set of fairly straightforward and standardized rules of usability and seldom get much contention from those involved in the design process. I’m more or less allowed to design according to my professional judgment.
Our Intranet is another ball game entirely.
The company I work for is a scientific consultancy and other than two other admin personnel like me, our entire staff is made up of scientists and technicians. They have a very diverse view of what’s good and what isn’t, and trying to please all of them on Intranet projects has been my biggest challenge.
Right now I’m working on adding an expense reporting system to the timesheet section of our Intranet. Employees will enter expenses they incur, including miles driven using a personal or company vehicle, purchases made with a company credit card, reimbursable expenses, travel, and even vendor invoices for large equipment or software purchased to be paid with a company check.
My development process is to interview a representative sample of key users and write down all the functionality needed and requested. I group everything into three categories: must have, need to have, and like to have. The ‘must have’ group is functionality that has to exist right out of the gate, version 1.0. The ‘need to have’ is functionality that will be built but doesn’t necessarily have to exist in the first release. The ‘like to have’ group is exactly that: something that is requested but not required, sort of “We’ll implement it if we can.”
Once that’s done, I create a clickable HTML prototype to let people see and touch the design. Several key users check it out and provide feedback about what works for them and what doesn’t. Feedback tends to fall within three types: Love it, hate it, or doesn’t care. How do I reconcile these disparate opinions about the system I’m building?
I can weigh the feedback based on where the responder exists in the corporate food chain. If a senior scientist likes something but a part-time seasonal technician hates it, who do you think will win out? What if two seniors have completely different opinions about the same functionality or design?
Although I create the designs based on my own experience and personal preferences, I try to leave my own likes and dislikes out of the equation, at least when it comes to aesthetics. When in doubt, I defer to the rules of usability and design. You’d be surprised how many people I’ve met that think hot pink text on a black background is beautiful. I have to rely on that experience and knowledge when settling disputes between users on aesthetic or usability issues as well.
If I have differing opinions about a design, and those opinions are more or less weighted the same, I’ll rely on usability standards to resolve the conflict and choose a design. Sometimes users don’t necessarily know what’s good for them. It sounds cold and almost arrogant, but people have a remarkable ability to forget they dislike something and simply get used to it. There are times, however, when I create a design or development functionality that violates my own judgment of what is ‘good’ for the sake of making the users happy. This sometimes works out okay, where a web site violates several rules of design or functionality but the users are happy with it so who cares in the end? That’s rare, however. Most often, when established rules are violated, things have to get redesigned after a while and we usually end up moving back toward the tried-and-true — where we [arguably] should have been in the first place.
In my position, at least on paper anyway, I have the final say when it comes to web development at my company. However, it’s rarely a good idea to pull rank if enough users don’t like what it would produce. Ultimately, happy users is what matters most.