Monday, April 8, 2013

G is for Generalization

This year, for the A to Z Blogging Challenge I'm posting alphabetically on topics related to software development...

Last time, I talked about future-proofing.

Generalization is a useful form of future-proofing. It involves thinking beyond what the business folks are telling you, and looking for ways to abstract ideas that might get stretched in future.

Opportunities for generalization often show up when your business users start listing off sets of possible values for data entities. Examples: "We've just got the head office here, and the store downtown." "We only sell this in red, white, and black."

Those are giveaway clues that you should have a table for those kinds of things, and not make assumptions that would limit future additions to the table.

Some opportunities are a bit more obscure, because they seem to be wedded to the way things work. Suppose a payroll system has a field on the employee record with a "W" for weekly-paid employees, and "M" for monthly. A short-sighted approach would end up with programs littered with decisions along the lines of 'If it's a "W" do this, if it's a "M" do that...'

Instead, a good generalization is to set up a table of pay cycles with the code (e.g. "W") along with some additional data to describe how employees of that type should be treated (e.g. "pay every 7 days, on a Friday").

The aim of this is to make sure that nowhere in your programming do you directly encode facts like 'If it's a "W" then today must be a pay day'. That question is always answered by looking up the pay cycle record and doing a calculation based on the associated data. And the aim is to make that calculation as generally-useful as possible. In the case of pay cycles, you might for example allow concepts such as "every x days" or "every x months" and some way of showing when the cycle ends. This might sound like a lot of effort, but the point is it is only going to be done once, in one place, so you can afford some extravagance here.

Why is that a good thing?

Imagine your business owner comes into your office one day and says, "Look, I know I said this would never happen (**), but management has just agreed to a new grade of staff, and - get this - they will be paid every two weeks!"

Do you want to be heading for coronary country imagining all those places where you encoded that M/W decision?

Or do you want to smile, add a third pay cycle to the table, and say "Done"?

(**) This is another giveaway phrase: The more strenuously a business user insists it won't happen, the more likely it will.

Saturday, April 6, 2013

F is for Future-Proofing

The world changes. Any application you build has to cope with change. Future-proofing is a frame of mind that equips your application with the flexibility to cope.

Good, clean design, modularity, separation of concepts, and good quality code, all make applications easy to change when the need arises. But future-proofing aims to reduce the need to change the application in the first place.

The biggest no-no I see, and have campaigned against endlessly, is where data is embedded directly in the code.

Some examples are obvious and clearly the result of short-sighted laziness. A programmer writes a routine to calculate tax, and sticks the tax rate right in the middle of the calculation. Why do that? You know taxes will change. The rate should be stored somewhere where it can be changed without having to delve into the code.

Better still, it should be something that a business user can change without involving application support at all.

Less obvious examples are more difficult to spot. The company name at the top of every screen and report, for example. Honestly, have companies never been know to change names? Make it a variable. It's just as easy. In fact, it's probably easier than typing the same thing over and over.

The real killers, though, are the constants that are so ingrained you don't even mention them in your design at all! For instance, what about all those monetary values with $ signs in front - are you sure that is fixed and forever? Try asking all those European businesses what fun they had when Francs and Deutschmarks and Lira gave way to the Euro.

My advice is to challenge any hard-coded value. Is it really fixed? Can you ever envisage a situation where it could change?

This is easily summed up as ... Constants are best regarded as variables.

Friday, April 5, 2013

E is for Error Messages


Translation: I've screwed up and you've just lost your afternoon's work.

Usually followed by that smug little "OK".

No, it's flippin' well not OK!

As an application developer, the best thing to do is to make sure these little beauties don't happen in the first place, of course. But, equally of course, computers will screw up from time to time, and when they do, the least you can do is make sure they do so gracefully.

So it's...

NO - to the cryptic techno-babble that the average end user won't even begin to comprehend.

NO - the end user will not want to debug the code. Don't even go there.

NO - the end user should not be left in limbo wondering what they should do next, or panicking that they've single-handedly brought the company system to its knees.

Things you can do

If possible, notify the help desk - behind the scenes - and log the technical details of the error somewhere a technical support person can get at them. The previous company I worked for used these measures very successfully. Often, by the time the user reported trouble, we were already working on a solution.

Keep the mumbo jumbo out of the visible message and instead tell the user what they should be doing next. Don't just leave them hanging. If you need them to stop work and report it, say so. If it's OK to log back in again and resume work, say so.

These are all talking about where the application chokes out of control. Then there's a whole class of errors that the end user will trip up over in the normal course of their work. Typing the wrong thing into a field, for example. These things should be detected by the application and the user informed in a way that is helpful and meaningful. Don't just spit out "Invalid input," say why it's not valid and what is expected instead.

Going the extra mile in handling errors will pay dividends in user satisfaction, and the extra effort in design and programming will repay you handsomely in the workload on your help desk.

Thursday, April 4, 2013

D is for Defensive design

This year, for the A to Z Blogging Challenge I'm posting alphabetically on topics related to software development...

Free Stock Image: Small Fortress Picture. Image: 245796
© Photographer Illreality | Agency: Dreamstime.com

So far, we've been pretty high up in the stratosphere, talking about architecture, business requirement, and core concepts. In contrast, this post can apply at all levels of design and development, but it is most at home down in the weeds of the code.

You reach a point in your program where you have a decision to make. A fork in the road. If the answer to a certain question is "Yes" you do one thing, if it's "No" you do something else.

The average programmer will likely code something that says: If "Yes" do one thing, otherwise do something else.

Notice the difference?

Where did "No" vanish to?

"What's the difference?" Average Joe-Coder protests. "It can only be yes or no, so if it isn't yes, it must be no. I'm just being efficient."

Sure, but you're not being defensive.

A defensive programmer will write code along the lines of: If "yes" do one thing, if "No" do something else, otherwise tell a bloody human that someone's f****d up!

"That's mad," Average Joe-Coder says. "Why code for something that can never happen?"

Fair point, if that were a true statement. But, despite Joe's insistence, it will happen ... some day. Trust me. You're relying on logic to ensure the only possible answers are yes or no, and that logic has been written by human beings - with all that implies. And computers are physical machines. They glitch sometimes. What went onto the disk as a nice clean "Yes" or "No" might overnight morph into "Whatever".

And, you might remind Joe, the more unlikely it is to happen, the more important it is to tell someone when it does.

If a stranger wanders into a public library, nobody cares. It's expected behavior, not a problem.

If a stranger wanders unchecked into the loading dock of the local supermarket, it's not expected, but plausible. There's no locked doors to stop it happening. A member of staff will likely ask, "Can I help you?" and it's not a big deal.

If a stranger walks unchallenged into the Queen's bedroom at Buckingham Palace, you can bet it will be a big deal and the authorities will want to know about it. Because that should be impossible.

But it has happened.

Defensive design makes no assumptions.

Face the unthinkable. Decide how to handle it, and act accordingly.

Wednesday, April 3, 2013

C is for Core concepts

Yesterday, I talked about business needs. They are important, but to get a feel for the shape of an application, I find it helpful to distil the core concepts out of the mass of detail.

Stock Images: Apple Slice Picture. Image: 29984
© Photographer Dana Rothstein | Agency: Dreamstime.com

Core concepts get to the heart of what is most important. It's essential to identify them because they will start shaping your solution very early on.

A good starting point is a high level data model. This highlights the most important things that the application deals with.

In an accounting application, for example, these might be accounts, transactions, and accounting periods. In a customer ordering system, core concepts might include customer, order, and inventory item.

At this point, you don't want to itemize every piece of data. The core concepts are the mountain peaks in the data landscape.

Another group of core concepts relate to function. What do you do with the things in your application? Again, you want to identify the really important things here, so maybe ask your business expert to describe in one sentence what is it the application does.

In a help desk system, the core of the system might be workflow - moving a call through different people's hands to fix an issue for the customer. A stock control system might revolve around movements in stock levels and forecasting future needs.

More subtle, and what people often overlook, are other qualities that might be important enough to affect your early architectural decisions. In a global application, maybe time zones, multi-lingual presentation and multi-currency accounting are important, whereas in an otherwise identical application for a local business these wouldn't matter. A booking system for a large airline or hotel chain might bring volume, performance, and high availability to the fore.

Core concepts may also arise from design choices. For example, security and privacy might be a primary business requirement. In response to this, you might decide that all data requests will go through an information access layer that enforces security policy. This design choice isn't a business requirement, but it is a crucial design concept that will fundamentally affect how the application is built.

So, picking out a handful of core concepts helps visualize what is most important, and helps de-clutter an unmanageable mass of information. You can then build the rest of your design around these concepts.

Tuesday, April 2, 2013

B is for Business needs

The purpose of software is to be useful to the people who use it.

Right?

So why is there so much crap out there?

All too often, software is designed with only minimal reference to the people actually using it. Worse still, a lot of software seems designed more for the aggrandizement of the writers than the use of the users - look how cool this feature is!

The point of software is not to show off how technically gifted you are. You can show me that by giving me something that does what I need it to do, reliably, without fuss, and without expecting me to know how it works.

And how can you possibly know what I need, unless you ask me?

The traditional software development lifecycle kicks off with Business Requirements. Good start! But gathering requirements isn't just about ticking off boxes full of dry jargon. To make software really useful, you need to dig beyond requirements. Requirements are what ivory tower dwellers say they need. A whole world apart from what the business, and the people in it, really need.

You need to dig. Keep probing. Keep asking "Why?" Ask at all levels, not just the bosses They don't have a clue. Sit with the people doing the job. Walk a mile in their shoes. See the world through their eyes.

For example, "The Requirements" might state that an order entry clerk needs access to a list of inventory. Great. Got enough to design the system? Off you go, then. You give them a spanking new screen that lays out the entire company's inventory any which way you can think of. By product category, by warehouse, search by name, by price, by color ... You spent days on it. You are proud of your job.

And the order entry clerks hate it.

"Why?" you ask them, "how unreasonable can you get? I put all this blood, sweat, and tears into this screen and you ungrateful chimps just don't appreciate the heartbreaking genius that went into it, with its predictive auto-completion and intelligent history-based searches."

"But," they say, "I already know the product number, I just need to see which is the nearest warehouse that has it in stock ... and I need to do that from within the order screen where I've already filled out half the order."

Oops. You didn't know that because you didn't talk to them about what they need.

The moment you catch yourself thinking, "Wow, everyone will love this new feature!" ... beware!

Monday, April 1, 2013

A is for Architecture

Before we start this year's A to Z Challenge, participants have been asked to say a big (and surprise) Thank You to Arlee Bird at Tossing It Out for starting this Challenge.

This year, for the A to Z Blogging Challenge I'm posting alphabetically on topics related to software development...

To kick things off, I want to be clear about one thing. This is not a geek series about programming. It doesn't even say much about technology. It is about the process of software development from a human perspective, and some habits of thought that I believe lead to good, robust, and useful software.

This first post is about architecture, which I think encapsulates the whole series.

When you say "architect", most people think of buildings.
Stock Photos: Beautiful Sacre Coeur In Paris Picture. Image: 68503
© Photographer Galina Barskaya | Agency: Dreamstime.com

No problem. What I'm talking about here is the essence of architectural thinking. That essence holds true in any field where your aim is to build something, be it a house, a three-course meal, or a piece of software. This essence, the thing that distinguishes an architect from a builder, is the use of deliberate planning and thinking skills to achieve a well-built end result that serves its purpose, is a pleasure to use, and which you are proud to be associated with.

In traditional building architecture, you may start with a blank slate, the big picture, and work things out from the top down. An empty field. What do you need to incorporate? Lay out the major elements and gradually fill in finer and finer detail.

Or you may start with one key idea and build out from there. The entrance hall. An imposing atrium. A courtyard with fountains. A shape.

Or you may start with some peculiar constraints. An unusually long and narrow plot. A steep hillside. The use of a particular material.

Wherever you start from, one thing that distinguishes good from poor architecture is that, although the dominant idea may be visible or even deliberately conspicuous, it won't dominate to the exclusion of all else. A breathtaking atrium may wow visitors to your headquarters, but the office space around it still needs to be useable. You don't get to skimp on ventilation, or disabled access, or fire safety, just because those pesky elements interfere with your grand vision.

Whatever your starting point, good architecture will arrive at a sound and coherent whole, where everything works and clearly belongs together.

The same applies in software development. You need to balance function (what it does) with a whole host of other constraints like useability, performance, security, auditability, availability, scalability, maintainability, and cost, to name a few.

A beautiful building doesn't happen by chance, and neither does beautiful software. In both arenas, there are deliberate and expert disciplines that need to be applied. These disciplines are your craft. You need to master them in order to produce good results reliably.

In other words, architecture is the art of doing things right by conscious design rather than purely by accident.
Related Posts Plugin for WordPress, Blogger...