For the sake of simplicity, let's just say Information Architecture means your navigation structure or the menu on your website. Now before all you IA experts out there grab your pitch-forks and prepare to storm the castle, please realize this article is directed at 'normal people', business owners who've had websites made and their developer contributed nothing towards helping them design a well thought-out navigation structure. This often happens because a web developer is a programmer, not an IA specialist (fair enough really, but still a problem).
The only thing I'll add by way of a simplistic explanation as to what IA is is this: it's also about how information is organised on your website, not just how you get to it.
The point of this article is to help people handle their own IA, and this is definitely possible. I personally don't believe basic IA is rocket surgery, anyone can understand it - there's no highfalutin technology concepts involved, or vague terms like 'on the cloud'. Most of it is just common sense, understanding your audience, and adapting your website to accommodate them ← that is the key point. Basic IA is about arranging your navigation and information in a way which best serves your audience.
Navigation design is about organizing information so: 1) people can find it (using their logic, not yours), and 2) successfully disseminating the information you want to get out there.
The 'disseminating information' part may sound peculiar, even contradictory considering I've just said it's about making information easy for users to find. Consider this though; you may be a charity organization and are required to make available certain information to satisfy government regulations. Or, there could be rules about using your website you need to tell people about. With this kind of information, most people (visitors) aren't interested in it, but it still needs to go up somewhere.
Now that the 'disseminating information' portion is out of the way, let's focus on how to 'do IA' on your website. The easiest way I believe is to approach the task by viewing your visitors in terms of customers. This still can be done even if people don't actually buy something from your website (i.e. I'm using the word 'customer' interchangeably with 'visitor').
Once you break down your visitors into different types of customers, you can start designing your menu structure and organizing your text to serve their needs. Some people will only have one 'customer type', whilst others will have four, five or more. The more 'customer types' you have, the trickier it gets to do IA (not impossible though, just more thought is required).
Let's take an online learning centre as an example. A website which offers online courses in areas such as English, mathematics, and so on. If we were to break down the major types of customers they have, we might come out with this: 1) students, 2) teachers.
Students are the ones using the website to access material such as study notes, quizzes, etc. Teachers are the ones that login and create the courses, answer questions from students, run webinars, and so on. Now this is a good starting point, but you may have noticed something. There is actually a sub-division to the concept of a 'student'. And this is very important. You can have a prospective student, someone who isn't a student yet, but would like to become one. This is subtly different to someone who is already a student. And the reason why this is important is because their needs are acutely different. On the one hand, a prospective student is probably going to be interested in what the enrollment fees are. Where-as an enrolled student is going to be interested in accessing online resources.
Identifying and understanding the different customers of your site is the key. Once you know this, you'll make reasoned decisions about what your menu structure should be like. This is why you sometimes see classifieds-style websites with very overt navigation elements like 'For Buyers' and 'For Sellers' ← they know these are users with very distinct needs.
Thinking about your information in terms of satisfying needs (or helping different types of people complete their particular tasks) is what will guide you when designing your menu structure, including what to name pages and where to put text.
About PM4Web
The PM4Web blog was born as an outlet to return knowledge back to the web development community. My goal is to share my experiences as a project manager from over the years in a manner which helps you succeed with your own projects.
05 November, 2014
29 October, 2014
If You Build It, They Will Come...
There's a belief out there that if you have a good idea for an online business, build the website and users will magically appear (what I call the "if you build it, they will come" mentality).
This worked for Kevin Costner in Field of Dreams, but for the rest of us that don't live in fantasy land, it doesn't turn out that way.
It's tricky to talk about this topic because it makes me sound like a kill-joy or naysayer. I don't like to stand in the way of anyone's dream, whatever it may be.
However, I often come across websites which obviously look unnurtured or abandoned (e.g. you do a search in major city for something and it comes up with '0 results'). The only thing missing is a Flash animation of a tumble-weed rolling across the screen.
For whatever reason, the site hasn't been successfully commercialized. My guess is usually that the business owner has spent all their money on technology, probably outsourced it overseas because it was too expensive to get done by a local digital agency. They most likely haven't budgeted for any significant form of promotion or marketing. This is like taking a raft to a river without a paddle, and thinking the current is going to get you across to the other side.
And this is what I mean by the "if you build it, they will come" mentality. Maybe this worked back in 1997 when there weren't many websites around to compete against, but now, big companies pour huge amounts of cash into promotion - competition is exceptionally fierce. Of course, in the absence of big dollars for TV spots, there's always viral marketing, but for most people this is easier said than done.
This worked for Kevin Costner in Field of Dreams, but for the rest of us that don't live in fantasy land, it doesn't turn out that way.
It's tricky to talk about this topic because it makes me sound like a kill-joy or naysayer. I don't like to stand in the way of anyone's dream, whatever it may be.
However, I often come across websites which obviously look unnurtured or abandoned (e.g. you do a search in major city for something and it comes up with '0 results'). The only thing missing is a Flash animation of a tumble-weed rolling across the screen.
For whatever reason, the site hasn't been successfully commercialized. My guess is usually that the business owner has spent all their money on technology, probably outsourced it overseas because it was too expensive to get done by a local digital agency. They most likely haven't budgeted for any significant form of promotion or marketing. This is like taking a raft to a river without a paddle, and thinking the current is going to get you across to the other side.
And this is what I mean by the "if you build it, they will come" mentality. Maybe this worked back in 1997 when there weren't many websites around to compete against, but now, big companies pour huge amounts of cash into promotion - competition is exceptionally fierce. Of course, in the absence of big dollars for TV spots, there's always viral marketing, but for most people this is easier said than done.
Another factor which hamstrings a website before it's even launched is the revenue model. Trying to charge people a subscription fee on an unproven platform is an uphill battle. What about banner advertising then? That's probably not going to work because the site doesn't have high enough traffic yet. A hall-mark of the current web epoch are websites that charge nothing (often they are looking for traction, then a buy-out later down the track). If established competitors are offering their services for free, then how on earth can a low traffic start-up hope to gain a foot-hold by launching and asking users to pay?
It's the dot com dream which lures people to the idea that web is easy money; this simply isn't the case. Sure, it costs far less to establish a website compared to opening a bricks and mortar shop. There's no factory equipment to buy, no materials used in production, cheaper insurance, etc. That's great, but you can have the most fantastic product in the world, but if no one knows about it, it's destined to fail.
I guess the point of this article is to not view a new website idea just in terms of the cost of the technology (i.e. paying programmers to build the thing). I often say to clients: "whatever budget you have for the website, have that again for marketing." The other advice I give people is this: "technology is the easy part, getting people to use the website is the hard part". Actually, the technology often isn't that easy when it comes down to it, but it's a relative measure - whatever headaches are experienced during the build phase, they are nothing compared to what's to come once the site is launched (i.e. attracting customers).
Does this mean it's all doom and gloom? Don't bother investing in a start-up idea, too hard, don't try? No, I don't believe that, I've partnered with business owners to developer online software knowing full-well the marketing budget was tight. Am I also guilty of the "if you build it, they will come" mentality? Perhaps, but the difference is I at least know before-hand visitors won't magically appear after launch.
It's the dot com dream which lures people to the idea that web is easy money; this simply isn't the case. Sure, it costs far less to establish a website compared to opening a bricks and mortar shop. There's no factory equipment to buy, no materials used in production, cheaper insurance, etc. That's great, but you can have the most fantastic product in the world, but if no one knows about it, it's destined to fail.
I guess the point of this article is to not view a new website idea just in terms of the cost of the technology (i.e. paying programmers to build the thing). I often say to clients: "whatever budget you have for the website, have that again for marketing." The other advice I give people is this: "technology is the easy part, getting people to use the website is the hard part". Actually, the technology often isn't that easy when it comes down to it, but it's a relative measure - whatever headaches are experienced during the build phase, they are nothing compared to what's to come once the site is launched (i.e. attracting customers).
Does this mean it's all doom and gloom? Don't bother investing in a start-up idea, too hard, don't try? No, I don't believe that, I've partnered with business owners to developer online software knowing full-well the marketing budget was tight. Am I also guilty of the "if you build it, they will come" mentality? Perhaps, but the difference is I at least know before-hand visitors won't magically appear after launch.
01 September, 2014
Are You Missing Out on Maintenance Dollars?
About 6 years ago I wrote an article explaining the support/maintenance system I use ('Maintenance Blocks' - Managing Change Requests). Back when I wrote the original article, the method was untested. I'm happy to report that it has turned out to be a solid and workable approach. To some degree this article is a follow-up, but I'll go into other methods in common use by freelancers these days for capturing those maintenance dollars.
A Quick Re-cap
There's a pervasive problem in the web freelance community when it comes to charging for support time, especially amongst those new to the world of contracting. The result is that freelancers miss-out on hundreds if not thousands of dollars each year in maintenance revenue they should be getting. The primary reason for this is thinking it's somehow bad to charge clients for 'quick bits of work'. Let's take a very realistic example, a client says: "hi John, can you update my company's phone number in our footer, thanks". For whatever reasons, the client doesn't feel like logging into the CMS and doing it themselves (still very common, no matter how easy CMSs get). Now, for a web developer this is about 3-5 minutes work, perhaps rounding it to 10 minutes when you include navigating to the particular client's website, logging into the CMS, and sending a confirmation when the task is done.
How do you bill for that 10 minutes? Do you send a client an invoice for 10 minutes worth of work? Not only is that a great way to alienate your client, but you're wasting your time and the client's time by adding unnecessary bureaucratic overhead to your day. What's that I hear you say? Why not just round up, have a policy of 1 hour being the minimum billable time for your work. Sure, you try that, send a client an invoice for $60 for 10 minutes worth of work, see how long that business relationship lasts.
So does that mean you should let it slide, it's just 10 minutes - chalk it up to good client relations right? Well, no, now you're not getting a fair deal there either. It all adds up, in a year, if you do four small tasks for a client, and they each take 15 minutes, that's an hour of legitimate billable work you've missed out on.
Hence the development of the 'maintenance blocks' protocol. This solves both problems where a freelancer isn't missing out on revenue, and a client isn't bugged with small invoices. In a nut-shell, the concept is like this: get a client to buy 'support hours' before-hand. Then when they ask for small pieces of work, you 'consume' these hours to undertake the work (with 15 minutes being the smallest 'consumable chunk').
From extensive use, I've found that clients are amicable to purchasing 2 hour blocks of support time each time. In a year, about 50% of my clients will purchase a second 2 hour block of support time. I have one large corporate client that buys 20 hour blocks, and they tend to use that up in 6-8 weeks (they're very active with upgrades and support requests).
I've encountered very little negative resistance to the 'support hours' system, business people can understand it and find the fairness in it. They 'get' how it works. They have a pool of support time, as they make requests, it decrements the time - everyone's happy.
There are other models for capturing support revenue out there, they are actually more profitable compared to the 'pay-per-task' approach I use, but personally I think the client gets a raw deal with these other systems. You may ask: "why wouldn't you use the most profitable mechanism for you?" I have my reasons, but suffice it to say that in the end it's up to the individual to decide what system they should use - but the key point is some system should be used.
Let's take a look at other common support models out there. An on-going monthly subscription plan is common here in Australia, especially when the website itself is built cheaply (i.e. the revenue model is based on recouping money over time, and then passive revenue into the future).
Another structure is where developers base support around charging a large amount for yearly hosting (more than the actual cost of hosting). Again, this provides passive revenue. Most business owners aren't aware of the price of hosting, that it usually costs next to nothing. So to receive a bill annually for $200 won't appear unusual.
On-going subscription payments are more profitable in the long run (hence why it's favored by so many web agencies). But I think these systems are unfair on the client, call me old fashioned, but I only like to ask clients for payment when I've actually done something for them.
I have a few closing notes I wanted to share regarding the maintenance protocol I use. I now refer to it as just 'support time' or 'support hours'; this is far more understandable to average clients compared to 'maintenance blocks' (← what was I thinking when I came up with that name?). Another improvement I made is to display the remaining amount of support time in each client's CMS:
By doing this, a client knows how much time they have up their sleeve, and it won't be a surprise when it comes time to 'top-up'.
With my more 'corporatey' clients, especially those that buy large chunks of support time, I have a 'maintenance log' page in the CMS which they can see. When I do work, I go in and add a line saying what I did and how much time it consumed (e.g. "1 hr - SEO RE title tag updates"). This is akin to timesheets you could say. The reason I do this is so the client feels confident about where their time has been going. I think this is important when you are asking a client to shell out over a thousand dollars to buy 20 hours of support time upfront. I know this sounds like a hassle, and to me it comes pretty easy considering I am a project manager. But when you send a client an email saying: "can I invoice you for another 20 hours of support time?" and they just say: "sure, go ahead" - it's all worth it. In that email, I also include a screenshot of the maintenance log, showing how their previous 20 hours had been used.
In situations where you're dealing with corporate clients, I'd encourage you to provide this level of tracking, budgeting is a key responsibility for decision makers in these environments. Arm them with the facts and your worth won't be questioned in your absence.
I've noticed over the years that even though I give clients a very easy-to-use CMS, about 80% of them still get me to do even the most basic updates for them. And this is exactly why a 'charge-per-task' support system is great.
Hopefully this revisit of the support system I use has been helpful to budding freelancers out there. Remember, your time is valuable just like everyone else, you deserve to be paid for the fruits of your labor. Don't undervalue your skills, but also don't take advantage of clients who've put their trust in you.
A Quick Re-cap
There's a pervasive problem in the web freelance community when it comes to charging for support time, especially amongst those new to the world of contracting. The result is that freelancers miss-out on hundreds if not thousands of dollars each year in maintenance revenue they should be getting. The primary reason for this is thinking it's somehow bad to charge clients for 'quick bits of work'. Let's take a very realistic example, a client says: "hi John, can you update my company's phone number in our footer, thanks". For whatever reasons, the client doesn't feel like logging into the CMS and doing it themselves (still very common, no matter how easy CMSs get). Now, for a web developer this is about 3-5 minutes work, perhaps rounding it to 10 minutes when you include navigating to the particular client's website, logging into the CMS, and sending a confirmation when the task is done.
How do you bill for that 10 minutes? Do you send a client an invoice for 10 minutes worth of work? Not only is that a great way to alienate your client, but you're wasting your time and the client's time by adding unnecessary bureaucratic overhead to your day. What's that I hear you say? Why not just round up, have a policy of 1 hour being the minimum billable time for your work. Sure, you try that, send a client an invoice for $60 for 10 minutes worth of work, see how long that business relationship lasts.
So does that mean you should let it slide, it's just 10 minutes - chalk it up to good client relations right? Well, no, now you're not getting a fair deal there either. It all adds up, in a year, if you do four small tasks for a client, and they each take 15 minutes, that's an hour of legitimate billable work you've missed out on.
Hence the development of the 'maintenance blocks' protocol. This solves both problems where a freelancer isn't missing out on revenue, and a client isn't bugged with small invoices. In a nut-shell, the concept is like this: get a client to buy 'support hours' before-hand. Then when they ask for small pieces of work, you 'consume' these hours to undertake the work (with 15 minutes being the smallest 'consumable chunk').
From extensive use, I've found that clients are amicable to purchasing 2 hour blocks of support time each time. In a year, about 50% of my clients will purchase a second 2 hour block of support time. I have one large corporate client that buys 20 hour blocks, and they tend to use that up in 6-8 weeks (they're very active with upgrades and support requests).
I've encountered very little negative resistance to the 'support hours' system, business people can understand it and find the fairness in it. They 'get' how it works. They have a pool of support time, as they make requests, it decrements the time - everyone's happy.
There are other models for capturing support revenue out there, they are actually more profitable compared to the 'pay-per-task' approach I use, but personally I think the client gets a raw deal with these other systems. You may ask: "why wouldn't you use the most profitable mechanism for you?" I have my reasons, but suffice it to say that in the end it's up to the individual to decide what system they should use - but the key point is some system should be used.
Let's take a look at other common support models out there. An on-going monthly subscription plan is common here in Australia, especially when the website itself is built cheaply (i.e. the revenue model is based on recouping money over time, and then passive revenue into the future).
Another structure is where developers base support around charging a large amount for yearly hosting (more than the actual cost of hosting). Again, this provides passive revenue. Most business owners aren't aware of the price of hosting, that it usually costs next to nothing. So to receive a bill annually for $200 won't appear unusual.
On-going subscription payments are more profitable in the long run (hence why it's favored by so many web agencies). But I think these systems are unfair on the client, call me old fashioned, but I only like to ask clients for payment when I've actually done something for them.
I have a few closing notes I wanted to share regarding the maintenance protocol I use. I now refer to it as just 'support time' or 'support hours'; this is far more understandable to average clients compared to 'maintenance blocks' (← what was I thinking when I came up with that name?). Another improvement I made is to display the remaining amount of support time in each client's CMS:
By doing this, a client knows how much time they have up their sleeve, and it won't be a surprise when it comes time to 'top-up'.
With my more 'corporatey' clients, especially those that buy large chunks of support time, I have a 'maintenance log' page in the CMS which they can see. When I do work, I go in and add a line saying what I did and how much time it consumed (e.g. "1 hr - SEO RE title tag updates"). This is akin to timesheets you could say. The reason I do this is so the client feels confident about where their time has been going. I think this is important when you are asking a client to shell out over a thousand dollars to buy 20 hours of support time upfront. I know this sounds like a hassle, and to me it comes pretty easy considering I am a project manager. But when you send a client an email saying: "can I invoice you for another 20 hours of support time?" and they just say: "sure, go ahead" - it's all worth it. In that email, I also include a screenshot of the maintenance log, showing how their previous 20 hours had been used.
In situations where you're dealing with corporate clients, I'd encourage you to provide this level of tracking, budgeting is a key responsibility for decision makers in these environments. Arm them with the facts and your worth won't be questioned in your absence.
I've noticed over the years that even though I give clients a very easy-to-use CMS, about 80% of them still get me to do even the most basic updates for them. And this is exactly why a 'charge-per-task' support system is great.
Hopefully this revisit of the support system I use has been helpful to budding freelancers out there. Remember, your time is valuable just like everyone else, you deserve to be paid for the fruits of your labor. Don't undervalue your skills, but also don't take advantage of clients who've put their trust in you.
01 May, 2014
Customization and Change in Software Development
For years I've been looking at APIs and protocols which speed up development but still confer a high degree of customization. Components, code libraries, CMSs and other such pre-packaged modules help with speed, but by their very nature they can stifle customization. By no means am I saying libraries aren't flexible, the good ones are, but sometimes the investment required to go 'off road' is so close to custom coding, you lose the initial benefit of using a library.
In a simplistic sense, the problem is illustrated by situations in which a client asks: "can you change this to...". Regardless of what development methodology you're using it, be it Agile or Waterfall, the time to make the change has to come from somewhere. What's that I hear you say: "don't worry, we have a change request budget factored into the project". That's good, very PRINCE2 of you, and for the most part this works great for small changes. What happens when a change request budget is exhausted, then what? You're in a situation where you have to ask for extra budget to cover off-spec work. Maybe you'll get the extra money, maybe you won't. Or you could take an Agile approach and say: "OK, we can put that in, but we have to drop another feature to cover the resource short-fall".
Although that scenario may sound perfectly reasonable to you and me, my experience has been that it's hard to convince clients to give up a previously agreed feature. It's like trying to get candy off a kid in a supermarket, once it's in their vice-like grip, they'll throw a tantrum should you try separating them from their prize. I do understand why it's a flawed proposition to say to a client: "if you want that feature, you'll have to sacrifice another." Why would they, they've thought up a good new feature, it has no connection to any other feature which was previously planned. It's a perfectly logical argument from an Agile perspective, we have limited resources, if the resources aren't increased, we need to trim back on previously agreed features.
This issue isn't as problematic for teams developing in-house software, they know and accept Agile principles, they can come to terms with dropping a good feature for a better one. But business owners aren't software designers, why should they understand this particular Agile concept? It's prioritization, and not everyone is good at that. Then there is the extreme version of this, Minimal Viable Product (or MVP). Anyone who can successfully sell that idea to a client should change their business card title to 'Lord of the Software', they are true smiths of the trade in my view.
Enter WordPress, Our Savior...
Let's say WordPress is currently viewed as a fabulous way of solving the problem of development speed + customization. It's all about pre-fabrication and bolt-on modules. The reality is WordPress isn't immune to the problem of customization, it's just faster at it. No API or code-base can perfectly predict and cater for the permutations that make each individual businesses unique. Plug-ins are essentially pre-packaged implementations of a [design] pattern, this is what WP excels at, but doesn't totally solve the problem of fast customization when it comes to deviations caused by unique business requirements.
Let's return to a statement of the problem: clients need customization in order to suit their specific business needs. What if we were to mangle this and say: "clients change their mind because they don't know what they want, thus putting strain on resources and injecting unpredictability into the project." I know saying "clients don't know what they want" sounds bad, but what it really means is business owners don't understand the software development process, nor should they. Does this then become a matter of 'education' - you could try that, but someone's got to be willing to learn in order to take in something new. Having the 'teach the client about software development' mentality leaves a lot to chance. Don't get me wrong, I try indoctrinate clients into the world of software development as much as I can, but I don't rely on this as a sole means of steering a project in a predictable manner (nor should you).
I've been trying to reduce the potential of clients changing things as much as possible from the onset. I do this by really probing them early on in the project, it's not just a matter of asking lots of questions, but rather the right questions. The goal is to avoid the potential for change once the project is underway. Now, this is only possible to a certain extent, you'll go crazy trying to cater for all situations. So if you can't know all possible outcomes ahead of time, what else can you do to instill predictably?
One approach I've been using for year which is very much in the spirit of Agile is suggesting options rather than asking the client exactly what they want. I know this may sound counter-intuitive, but sometimes it's easier to tell someone what you don't want, rather than what you do. The premise being that by removing the unwanted options, you're left with a pool of viable options. In practical terms, it's the difference between saying: "how do you want this?" compared to "we can do it this way... or this way... or another option is...".
By taking this approach, you reduce the risk of stakeholders changing their mind later down the track (reduce, not remove). By offering possibilities, you're helping with the issue of the client not knowing what they want (maybe they don't know what's possible, so you tell them). To me this also seems like proper consultative service, rather than expecting a client to design what they want. A client should only have to tell you what the end goal is, or what task their user is trying to achieve, then it's up to the software designer to make it so.
Subscribe to RSS Feed.
In a simplistic sense, the problem is illustrated by situations in which a client asks: "can you change this to...". Regardless of what development methodology you're using it, be it Agile or Waterfall, the time to make the change has to come from somewhere. What's that I hear you say: "don't worry, we have a change request budget factored into the project". That's good, very PRINCE2 of you, and for the most part this works great for small changes. What happens when a change request budget is exhausted, then what? You're in a situation where you have to ask for extra budget to cover off-spec work. Maybe you'll get the extra money, maybe you won't. Or you could take an Agile approach and say: "OK, we can put that in, but we have to drop another feature to cover the resource short-fall".
Although that scenario may sound perfectly reasonable to you and me, my experience has been that it's hard to convince clients to give up a previously agreed feature. It's like trying to get candy off a kid in a supermarket, once it's in their vice-like grip, they'll throw a tantrum should you try separating them from their prize. I do understand why it's a flawed proposition to say to a client: "if you want that feature, you'll have to sacrifice another." Why would they, they've thought up a good new feature, it has no connection to any other feature which was previously planned. It's a perfectly logical argument from an Agile perspective, we have limited resources, if the resources aren't increased, we need to trim back on previously agreed features.
This issue isn't as problematic for teams developing in-house software, they know and accept Agile principles, they can come to terms with dropping a good feature for a better one. But business owners aren't software designers, why should they understand this particular Agile concept? It's prioritization, and not everyone is good at that. Then there is the extreme version of this, Minimal Viable Product (or MVP). Anyone who can successfully sell that idea to a client should change their business card title to 'Lord of the Software', they are true smiths of the trade in my view.
Enter WordPress, Our Savior...
Let's say WordPress is currently viewed as a fabulous way of solving the problem of development speed + customization. It's all about pre-fabrication and bolt-on modules. The reality is WordPress isn't immune to the problem of customization, it's just faster at it. No API or code-base can perfectly predict and cater for the permutations that make each individual businesses unique. Plug-ins are essentially pre-packaged implementations of a [design] pattern, this is what WP excels at, but doesn't totally solve the problem of fast customization when it comes to deviations caused by unique business requirements.
Let's return to a statement of the problem: clients need customization in order to suit their specific business needs. What if we were to mangle this and say: "clients change their mind because they don't know what they want, thus putting strain on resources and injecting unpredictability into the project." I know saying "clients don't know what they want" sounds bad, but what it really means is business owners don't understand the software development process, nor should they. Does this then become a matter of 'education' - you could try that, but someone's got to be willing to learn in order to take in something new. Having the 'teach the client about software development' mentality leaves a lot to chance. Don't get me wrong, I try indoctrinate clients into the world of software development as much as I can, but I don't rely on this as a sole means of steering a project in a predictable manner (nor should you).
I've been trying to reduce the potential of clients changing things as much as possible from the onset. I do this by really probing them early on in the project, it's not just a matter of asking lots of questions, but rather the right questions. The goal is to avoid the potential for change once the project is underway. Now, this is only possible to a certain extent, you'll go crazy trying to cater for all situations. So if you can't know all possible outcomes ahead of time, what else can you do to instill predictably?
One approach I've been using for year which is very much in the spirit of Agile is suggesting options rather than asking the client exactly what they want. I know this may sound counter-intuitive, but sometimes it's easier to tell someone what you don't want, rather than what you do. The premise being that by removing the unwanted options, you're left with a pool of viable options. In practical terms, it's the difference between saying: "how do you want this?" compared to "we can do it this way... or this way... or another option is...".
By taking this approach, you reduce the risk of stakeholders changing their mind later down the track (reduce, not remove). By offering possibilities, you're helping with the issue of the client not knowing what they want (maybe they don't know what's possible, so you tell them). To me this also seems like proper consultative service, rather than expecting a client to design what they want. A client should only have to tell you what the end goal is, or what task their user is trying to achieve, then it's up to the software designer to make it so.
Subscribe to RSS Feed.
20 April, 2014
Programming Style Guide for Classic ASP
The purpose of this article is to present a basic yet complete coding style guide which you can use with your development team.
General Rules
The reason why a programming team has a style guide is for the sake of conformity. In other words, even though the code is worked upon by 3-4 different people, it should all look like it’s been written by one person. Conformity leads to better maintainability in the long run (e.g. bug fixing becomes faster and adding new features gets easier).
There are 3 ‘golden rules’ which should be followed when coding on projects, they are:
1. Functions should be no more than one screen length in size
2. Don’t do anything clever
3. Don’t do anything stupid
2. Don’t do anything clever
3. Don’t do anything stupid
Further explanation...
Functions should rarely be longer than one screen length in size. If you find you've written a function which is longer than one screen length in size, try break out a block of code into a separate smaller function if it makes sense to do so.
Also, if you see your function is performing two distinct tasks or operations, break it out into two smaller functions. For example; imagine you are calculating a user’s age, and then displaying their profile in the one function; that should be broken into two separate functions. This rule isn't always practical, you will occasionally get a long function if you have a large switch statement. You'll also get a long function if you have HTML/UI code to render. But at least 8 out of 10 times, functions can be written which are no more than a screen-full in size, this is definitely possible.
The reason why you should be writing small functions is utilising the OOP principle of modularisation. In the long run, this improves the maintainability of code and reduces bugs by breaking up tasks (functions) into smaller units. Imagine you have to come back to debug a block of code 3 months after writing it. Most likely your memory of the function would have begun to fade, it’s easier and quicker to get re-acquainted with a smaller block of code. Also, consider the very real possibility of someone coming back to debug your code, it’s going to be easier for them to understand a smaller block of code vs. a large slab of code.
“Don’t do anything clever” means don’t write unnecessarily complicated code. If you can write 3 lines of code which is easier to understand than 1 line of compact code and does the same thing, write 3 lines. Again, this comes back to maintainability. Someone else may need to debug your code later down the track, so do what you can to make it easier for. If it’s a very straight forward line of code, then it’s OK to put it on a single line - e.g.:
if (strFirstName = "") then Exit Function end if
“Don’t do anything stupid” isn’t about making mistakes, mistakes are mistakes - they happen, we’re all human. What we are talking about is doing things where you know better. For example: checking-in code before testing it, or not backing-up files before making major changes, or changing a password and not letting other people know about it, or having a problem with your work and keeping it to yourself, rather than telling your manager and asking for help.
CSS
This section relates to writing CSS code which is used by the software's front-end.
Class names should always be all lowercase:
Good: login_user_name
Bad: Login_User_Name
Separate each word with an underscore (not a space):
Good: login_user_name
Bad: loginusername
If you need to create a new CSS class, it must be placed in the
\css\main.css
file (or whatever file is considered the main CSS file for the software).
If you need to create a whole new CSS include file, it should be placed inside the
\css\
folder. Creating an entirely new CSS include is rare, it would only happen if for example you were adding a large new sub-system to the project (e.g. forum.css
).
CSS class names should be descriptive, but generally no longer than 3 words:
Good: menu_hover_over
Bad: m_hoverover
ASP Code
Even though vbScript is a loosely-typed language, it’s advisable to prefix variables with a data type. This occasionally helps with debugging as bugs occur due to data type mismatches.
Use the following data type prefixes:
i = for integer (e.g. iCounter)
str = for strings (e.g. strStudentName)
f = for floats (e.g. fDollarAmount)
obj = for objects (e.g. objRecordSet)
b = for bools (e.g. bRtnValue, bHasBeenDeleted)
...Arr = for arrays (e.g. strArrWeekdays, iArrProductIDs)
str = for strings (e.g. strStudentName)
f = for floats (e.g. fDollarAmount)
obj = for objects (e.g. objRecordSet)
b = for bools (e.g. bRtnValue, bHasBeenDeleted)
...Arr = for arrays (e.g. strArrWeekdays, iArrProductIDs)
When using bool values, use the naming convention of bHas... or bIs... (e.g.
bHasExpired
or bIsVisible
). This naming approach results in more readable code since you can write 'English-like' questions, for example:
if (bHasBeenDeleted = true) then...
Use camel notation for variable names:
Good: strFirstName
Bad: strfirstname
Bad: str_first_name
Generally, underscores aren’t used with variable names. The exception to this rule is global variable (which should be rare anyway), these should be prefixed with a g_...:
Good: g_strUserName
Bad: gstrUsername
Use descriptive variable names rather than short indistinct ones, but within reason. Try describing the variable within 3-4 words at most:
Good: iCounter
Good: iNumberOfStudentRecords
Bad: x
Bad: i
Bad: iTotalNumberOfStudentRecordsReturned ← unnecessarily long
It’s better to have a variable name like
iNumberOfItemsToShow
than iNoItems
. Descriptive variable names make code more readable, which improves maintainability in the long run and reduces debugging time. Imagine you have to come back to debug your code 3-4 months in the future, the code won’t be fresh in your mind. Also, think about people who may have to debug your code, descriptive variables will help them.
When working with arrays, consider creating constants to use with them. This is especially helpful if the array is intended for use within more than one function. For example:
const EMAIL_SUBJECT
const EMAIL_MESSAGE_BODY
strArrEmailTemplate(EMAIL_SUBJECT)
strArrEmailTemplate(EMAIL_MESSAGE_BODY)
const EMAIL_MESSAGE_BODY
strArrEmailTemplate(EMAIL_SUBJECT)
strArrEmailTemplate(EMAIL_MESSAGE_BODY)
This makes it clear what data is being held in the array element. This in turn reduces the risk of bugs in the long run.
Functions
This section talks about how functions should be written within code.
At the beginning of most include files (.inc), there should be a start-up function (e.g.
BlogStartUp()
). This is generally used for initialising global variables used within the module/include file:
Function BlogStartUp()
g_strArticleID = Response.QueryString("article_id"))
End Function
g_strArticleID = Response.QueryString("article_id"))
End Function
We use camel notation for function names, except the first letter of the function is always capitalised:
Good: LoginStartUp()
Bad: loginstartup()
Long function names are better than short undescriptive ones (within reason):
Good: GetNumberOfActiveStudents()
Bad: GetVal()
Bad: ProcessStudentRegistrationInformation() ← that’s far too long
You must use local variables as much as possible and pass values to functions, rather than rely on global values. It’s OK to use global variables occasionally, you just shouldn’t rely on them too much.
If you find you need to pass a large number of values into a function (e.g. 10+), consider passing an array of values instead. For example:
Good: Call SaveStudentData(strArrStudentDetails)
Bad: Call SaveStudentData(strStudentName, iAge, iEnrollmentStatus, iStreetAddress, strSuburb, strZip, iCampus, iGender, iCourseCode)
If you have a recordset object, you’re better off passing it to a function ByRef rather than sending a big list of parameters. For example:
Function DrawStudentSummaryList(ByRef objRecordSet)
When writing a new function, think about including some basic error checking if it makes sense. This is especially important when the function needs a passed value to work. For instance, imagine a SQL query like this within a function:
strSqlQuery = "SELECT * FROM tbl_users WHERE (status = " & iStatus & ")
What would happen if the iStatus parameter was empty? You'd get a script error. To avoid the danger of a crash, you should add a line of code at the top of the function which looks like this:
if (iStatus = "") then Exit Function end if
When a function is created specifically to return a value, prefix it with the word
Get...()
, for example:
Function GetAccountStatus()
Function GetNumberOfTickets()
Function GetUserFullNameByID()
Function GetNumberOfTickets()
Function GetUserFullNameByID()
Functions which perform some form of processing and then return a value should have a specific variable which has the data type plus the word
...RtnValue
. For example:
strRtnValue
iRtnValue
bRtnValue
iRtnValue
bRtnValue
When a function is written to save a value of some kind, it should generally be prefixed with the word
Set...()
, for example:
Function SetActiveMenuItem()
Function SetUserLastLoginTime()
Function SetUserLastLoginTime()
If a function contains HTML code and is rendering front-end UI of some kind, it needs to be prefixed with either Render...() or Draw...(), and post-fixed it with the word ...HTML(). For example:
RenderLoginBoxHTML()
DrawDateDropListHTML()
DrawDateDropListHTML()
Query Strings
When creating query string variables to be passed via hyperlinks, they should be named all lowercase with underscores in place of spaces. If an ID is being passed, then the query string name should end with ..._id (e.g. blog.asp?blog_id=45). Query string variables should be descriptive, but generally no longer than 3-4 words in length:
Good example:
<a href="blog.asp?blog_id=1">Buying a Cat</a>
Bad example:
<a href="blog.asp?ID=1">Camping</a>
Form Controls
Form fields should be named in a manner which gives an indication of their control type, for example:
<input type="text" name="txt_age" value="" maxlength="8" />
<input type="checkbox" name="chk_agree_to_terms" value="1" />
<input type="radio" name="rdo_gender" value="1" />Male
<textarea name="txt_about_me"></textarea>
<select name="drp_day"><option value="1">1</option></select>
This naming convention can be useful when it comes to server-side logic. Knowing the control type helps with debugging or processing data before inserting it into the database.
Notes:
1) textbox controls should always have their maxlength attribute set
2) textarea controls use the same prefix as textbox controls (it’s just text after all).
If you need to use an ID with a control due to JavaScript interactivity, the naming convention for IDs has the control type at the end rather than as a prefix. For example:
<input type="text" name="txt_age" value="" id="age_textbox" />
<input type="checkbox" name="chk_tax" value="1" id="tax_checkbox" />
<input type="radio" name="rdo_join" value="1" id="join_radio" />Yes
<textarea name="txt_about_me" id="about_me_textarea"></textarea>
<select name="drp_day" id="day_droplist"><option value="1">...
Note: the ID attribute is named differently to the form control name to avoid confusion between the two.
File Names
This section relates to the naming conventions used for all files found within the website’s folders.
File names should always be all lower case and use underscores instead of spaces:
Good: database_connection.asp
Bad: Database Connection.asp
Longer descriptive file names are preferable to short ones which give no indication of what the file is (within reason). Usually a maximum of 3-4 words will do:
Good: duplicate_username_check.asp
Bad: dup_check.asp
Bad: perform_duplicate_username_check_operation.asp ← too long
These same rules apply for all other file types like JPEGs and PNGs (note: GIFs are rarely used these days, they’ve mostly been replaced by PNGs).
The reason for descriptive file names is it helps when trying to identify what a particular file does amongst a larger list of files without having to open up the file.
Database
This section covers conventions to be used when working with database tables and fields.
The rules for naming database tables are as follows:
• use only lowercase characters
• use underscores in place of spaces
• table names are prefixed with the letters tbl_
• table names should rarely be more than 3-4 words in length
• tables should nearly always end in ‘s’ (indicating plural)
• use underscores in place of spaces
• table names are prefixed with the letters tbl_
• table names should rarely be more than 3-4 words in length
• tables should nearly always end in ‘s’ (indicating plural)
For example:
Good: tbl_students
Good: tbl_countries
Bad: Error Code ← should be: tbl_error_codes
Bad: UniversityStudentRecordDetails ← too long
Datababase fields should follow these rules:
• use only lowercase characters
• use underscores in place of spaces
• primary and foreign keys must start with id_
• rarely be more than 3-4 words in length
• use underscores in place of spaces
• primary and foreign keys must start with id_
• rarely be more than 3-4 words in length
For example:
Good: id_student
Good: first_name
Bad: enrolmentStatus ← should be: enrolment_status
Bad: recordID ← should be: id_record
Note: one of the reasons why primary keys always start with id_ relates to protecting against SQL-injection hacks. You can have a wrapper function like
QStr()
and RForm()
which strip the characters id_ from strings.
When creating fields used to store a bool condition (e.g. yes/no, active/inactive, show photo/don’t show photo, etc) - use a tinyint data type rather than a bit. 1 is used to indicate true and 0 represents false. Using an int provides flexibility in case more conditions are added in future (e.g. 1 = active, 0 = inactive, 2 = suspended).
Subscribe to RSS Feed.
Subscribe to:
Posts (Atom)