- We design and build extraordinary applications for companies looking to make the next great idea a reality.
- learn more
800 on Your Math SAT, Software Development and Bugs
Why don't more people get a perfect score on the math portion of the SAT? I mean its dead simple -- just simple arithmetic. And there are plenty of bright young things that understand the problems cold.
I can understand stubbing your toe on the verbal; after all, there may be a word in the test that you just don't know or remember. But the math? There aren't more than a half dozen problems, and though the numbers may change, the concepts don't. So why don't more people get a perfect 800 on their math portion?
I ask this question every time someone asks me why there are bugs in software.
Topics: Agile Development, Best Practices
The User Interface is the Root of All Evil
I'm into my third decade of developing software now. I've gone from Structured Design, to OOAD and SOA; from waterfall to RUP to Agile. There is one aspect of software development that has remained fairly constant in all of that time: nothing causes as much complexity and bad architecture and design as the user interface.
I'm not saying that MVC or PAC based UI's are complex to design and implement, though they can be. Rather, I'm saying that the user interface can infect the rest of your system -- the domain model and other business logic -- leading to a poorly designed and hard to maintain system.
Topics: Best Practices, User Experience
Use a Task Flow to Show “How do I ___?”
Although task flow diagrams (sometimes referred to as interaction flows, process flows or work flows) are a standard in most IA’s toolkits, it can be confusing for those unfamiliar with this particular tool to know when to start diagramming. When in the process is it started? How much information is needed before diagramming? How much detail should be added? When is it considered complete?
The short answer is to start diagramming once the task is identified because it’ll help in flushing out the requirements. The diagram starts to identify what the user and the system need to do. It delineates a repeatable pattern of activity. It answers the question: “How do I _____________”.
After you have an identified task (I like to use Use Case Diagrams to call out the high-level tasks), the start point and end point need to be established. For example, let’s say your business requirements state that the web application is only accessible by authenticated users; therefore, a user needs to successfully login in order to see the home page. The initial diagram has the user starting on the login page, submitting their information and viewing the home page after the system logs them in.
But wait … I did say *successfully* login, didn’t I. O.k., so we add a decision point to the diagram to show that only successful logins allow a user to access the web application. Don’t worry just yet what the details are for the system to successfully authenticate a user. The purpose of the diagram is to identify the process, not to define it. For now, all that's needed is to show that the login information must be vetted before the system allows access.

Granted, the previous examples are simplistic, but simple is where task flow diagrams start. This basic statement “How do I ____________” turns into an initial task flow, delineating the steps needed to complete the task from start to finish based on the information known at that time. The first iteration is generally the ‘happy path’ and identifies the main flow of a task. As more steps are uncovered through requirements, the flow is updated and modified to accommodate the new information and show the various decision points and/or alternative paths as they become known. The end result is a flow diagram that conveys both the overall structure of the main user tasks and the sequencing of activities to be programmed into a repeatable activity.
Topics: Best Practices, Information Architecture, Task Flows
Ajax Testing: Doubling Down with Selenium and JMeter
This idea comes from my colleague John McCaffrey, but since he's having a bad case of blogger's block, I get to post about it.
For anyone who has developed tests for web applications with a tool like Selenium (or Watir), you know it is a sysiphean task, rolling the boulder of automated tests up the hill of a constantly changing application. The DOM changes, the text changes, the url's and parameter's change, iframes and onload events don't always play nice with your test recorder. Depending on the framework you are using, id's may change in unpredictable ways, forcing you to hack together brittle xpath expressions. Still, functional testing is important, so you persevere, spending countless hours in making those tests run clean.
Topics: Ajax Development, Best Practices, Selenium, Testing
Use Case Diagrams
Projects start off at the 60,000 foot level -- the client wants a widget that allows their users to do X, Y & Z -- and need to be brought down to a level of detail where coding can begin. Something I use to start this process is a version of the UML Use Case Diagram.
For those of you not familiar with it, a Use Case Diagram describes the needed functionality in a system. Unlike flow diagrams, however, the use case diagram doesn’t represent the order or number of times the functionality needs to be executed and it doesn’t display any subroutines. Instead, it’s a high level diagram that identifies the primary tasks an actor/persona needs to be able to do.
The beauty of this diagram is that you’ve now captured the overall view of what the system needs to be able to do in order to allow the user to complete all their tasks. With the high level activities clearly identified, the diagram easily lets you communicate with your client and get their sign off that the needed functionality has been accurately captured. From here, the team can move onto further defining what’s needed to support this functionality: data modeling, user stories, task flows, etc.
Topics: Best Practices, Design, Information Architecture
Stop, Reload, Error Loading Page 404: Converting Web 1.0 to 2.0

OK, onwards in our effort to convert Web 1.0 apps to Web 2.0. Today we'll focus on some of the differences between Web 1.0 and 2.0 from the user experience perspective. When we think about our web interface, we usually think about the links, forms and controls we've put in place. But the reality is that often things go wrong with our app -- sometimes network problems, system problems or application errors -- and we get errors like 404 or 503, or a "page did not load." How does the user respond to these issues?
Usually they make use of the Stop, Reload, Back and Forward buttons. Most times application developers see the use of these browser buttons as a problem, to be mitigated ("Please don't submit this form twice..."; "Don't use the back button or your order will be submitted twice..."). If you think about it a little more carefully, you'll find that these buttons form a vital safety net for web applications, without which users would be crying in frustration at the "Unable to connect..." pages and spinning cursors that have brought your app to a halt.
Topics: Ajax Development, Best Practices, Tutorials, Web 2.0, Web Development
Put on Your X-Ray Specs: Converting Web 1.0 to 2.0
I've blogged in the past about converting Web 1.0 to Web 2.0. There were and still are three options:
- The Christmas Tree Approach - decorate your existing Web 1.0 application with lots of snazzy Ajax widgets. It's quick, but it's a bear to maintain.
- The Version 2.0 Approach - scrap your existing app and develop a Web 2.0 version from scratch. This can take a while and suffers from the same issues that all version 2 projects do, i.e. if version 1.0 has evolved over time, capturing full requirements may be challenging.
- The Resurfacing Approach - keep your backend logic, but rewrite the interface as a single page, desktop-like GUI.
This last approach has many advantages: it's quicker and less expensive than #2, but easier to maintain and gives a more unified user experience than #1. It also has some of it's own pitfalls. Mostly, the issues are around some of the hidden assumptions of a Web 1.0 applications that expects all interaction to occur through a postback.
So, what's the plan? How do we go about converting our 1.0 app via resurfacing? To do this you have to put on your X-ray specs, so to speak, and look at the bones of your application. If you're already using an MVC framework, your ahead of the game. So, what are the analytical steps?
Topics: Ajax Development, Best Practices, Tutorials
Agile Development: Pipelining

Sometimes you can roll into an iteration or sprint with a handful of high-level user stories and refine as you go. But if you have a very complex system with lots of interdependencies, or are trying to incorporate a high level of user experience design, or your domain experts aren't readily available to you on a daily basis, then your requirements have to be a little more refined up front.
The answer isn't to go to a waterfall process and bang everything out months in advance. The answer, rather, is to pipeline requirements and development. In practice, the functional team -- made up of Business Analysts and Interaction Designers -- focuses on the requirements for sprint n+1 during sprint n, while the development team focuses on developing the features for sprint n. You can, and should, extend this further: the QA testing team should work on building the automated tests for the features developed during sprint n-1 in sprint n. Anther way of saying this is that the development team is looking at now, the function team is looking one sprint ahead, and the testing team is looking one sprint behind.
While the feedback isn't as tight as if you were to do all of this in one sprint, it's still pretty far away from waterfall. One thing worth pointing out is that this doesn't mean that you do no testing or requirements gathering for sprint n in sprint n, just that the bulk of it happens in the sprint preceding and following the current one. Also, the development team will be involved in the requirements gathering somewhat, but they won't be forced to context switch between what they are working on now and what they will be working on in the next sprint. And they'll definitely get to ask all of their questions in the next sprint planning meeting.
Anyhow, if you find yourself wrestling with trying to jam requirements, development and testing all into one sprint, give pipelining a try.
Technorati Tags: agile, sprint, pipelining
Topics: Agile Development, Best Practices
Ajax security surprises: web-aggregators, offline applications and frameworks

I'm still absorbing the densely packed information from "Ajax Security," the first-rate book by Billy Hoffman and Bryan Sullivan that I recently recommended in these pages. Here, in no particular order, are three of the most surprising lessons imparted by Messrs. Sullivan and Hoffman:
Web aggregators and SSL
This is probably a great big "duh" to some developers, but web aggregators such as iGoogle and NetVibes often compromise the security of otherwise SSL-encrypted web applications when funneling content from them to your personalized homepage:
Now, consider what happens when you use a Gmail widget on an aggregate site like NetVibes. Sharp-eyed readers will notice the URL for NetVibes ... is http://www.netvibes.com. This is not an encrypted connection! NetVibes sends user data in the clear from the aggregate to the user.... NetVibes makes an SSL connection to Gmail, and then NetVibes degrades the level of security by transmitting the data over an unencrypted connection. Our attacker ... can steal the data much more easily now. NetVibes is not providing the same level of security that a user would receive if he accessed Gmail directly. This situation is not unique to NetVibes and Gmail.... At the time of publication, every major aggregate Web site the authors examined downgraded security on data from secure sources. [emphasis theirs]
Topics: Best Practices, Books, Review, Security
Save That Duck!
So, while most of you were off celebrating the holidays, Dietrich was off killing a duck, or at least Duck Typing. Personally, I always thought that the goose was the traditional holiday bird.. shows what I know.
Deitrich's argument is that Duck Typing does not allow "Dead Duck Typing", being able to restrict access to part of an object's state or functionality. The classic case here is keeping a display layer from getting at the persistence layer. (Maybe we can call this Stephen Colbert Typing, since you're declaring part of the object as "dead to me"...)
Dietrich closed his post with:
Some will argue this is a Java-ism creeping into Ruby. I say this is just plain old-fashioned good OO design.
Which I think is my cue.
I understand the theoretical argument for having strict (or stricter) access control in a system, and I certainly understand why having small, high cohesion classes is a good thing. My problem is that it's very rare for me to have a practical issue in a system because of loose access control or overly generous interfaces (granted, I've had a good run of working with smart people). On the other side, I commonly find that when I'm writing a program with access control I'd like to do something more flexible with an object, but I can't, because the original writer of the class did not anticipate the usage.
Specifically on the Ruby side, it's actually not hard at all to restrict access to an object. ActiveRecord objects can easily be made read only called before being passed to a view to protect from inadvertent changes.
In the more general case, it's not hard to do something like this, which only allows certain methods of an object to be called:
class ArbitraryProxy
def initialize(object, *methods)
@object = object
@methods = methods
end
def method_missing(method, *args)
if @methods.include? method
return @object.send(method, *args)
end
super
end
end
x = ArbitraryProxy.new("abcd", :size, :gsub)
p x.size
p x.gsub("b", "---")
p x.upcase
This returns:
4 "a---cd" NoMethodError: undefined method ‘upcase’
The interesting thing is that, by and large, Rails developers don't feel the need to do this. I don't think I've ever seen an authoritative source suggest that it's best practice to make ActiveRecord objects read only before passing them to the view.
There is a Rails plugin called Liquid that enforces the use of proxy objects before being passed to the view. It's not very widely used (in part because creating the proxies is kind of a pain).
I don't see that Ruby and Rails programmers see this issue as a practical problem facing them (it helps that Ruby tends to encourage small classes in other ways). That said, there are clearly cases where you need to be extra careful. Liquid is used as user-facing templating engine for a blog tool, which is clearly a case where you'd want to limit the damage that your template writers can do.
But I see that as the exception, not the rule. Long live the Duck!
Coming Soon: Professional Ruby on Rails -- available in bookstores Mid-Februrary.
Technorati Tags:
ruby, OOAD, Duck Typing
Topics: Analysis, Best Practices, Design Patterns, Ruby on Rails
The Curse of Knowledge
You can never know too much about something, right? Wrong, at least according to a December 30th article in the New York Times. As we become experts in a particular domain, our ability to innovate diminishes.
"Andrew S. Grove, the co-founder of Intel, put it well in 2005 when he told an interviewer from Fortune, “When everybody knows that something is so, it means that nobody knows nothin’.” In other words, it becomes nearly impossible to look beyond what you know and think outside the box you’ve built around yourself."
Reading the article, I couldn't help but think back to my own experiences with this same sort of issue. I blogged recently about two related ideas: how interface designers are sometimes guilty of thinking as designers--when they should be thinking as users, and about the mixed bag that is competitive research, which can limit the designers creative thinking by boxing them into predefined solutions.
Now I see that it's part of a larger problem of expertise and creativity. The more expertise one exhibits in a particular field, the harder it is to think creatively--to so called think 'outside the box', and the harder it is to imagine not knowing what you do. The problem affects whole companies, as a certain way of thinking becomes entrenched, and it gets harder for it to adapt to a changing landscape. The article cites the example of Eveready, the flashlight maker, who's powers-that-be couldn't imagine that their product could be effectively marketed to anyone other than men shopping at hardware stores.
According to Cynthia Barton Rabe, author of “Innovation Killer: How What We Know Limits What We Can Imagine — and What Smart Companies Are Doing About It,” the solution for Eveready, as for any organization bogged down in its own expertise, is an infusion of outside thinking. Bringing the so called novices--the non expert users--into the discussion at the early stages of design, weather it be product or strategy design, opens the door for new ways of thinking that experts have long been insulated from.
Powered by ScribeFire.
Topics: Best Practices, Design, Design Patterns, Domain Knowledge, Ideation, Story Telling
Dead Duck Typing and High Cohesion
I'm sure you're familiar with Duck Typing, in particular as espoused in the Ruby world: "If it walks like a duck and quacks like a duck, I would call it a duck." Nothing is an unmitigated good, but Duck Typing, or designing against interfaces, is generally a good thing. It allows you to abstract away the implementation details, which is a very good thing in the OO world. One thing missing from Ruby, however, is Dead Duck Typing, i.e. when you cook the duck in the oven, you probably don't want it walking and quacking.
Why wouldn't you just have a different class or object, a "Roast" object that you construct when you kill a duck? Well, you might want to do that, sort of like a "Duck Transfer Object," or DTO. But in some cases, creating a separate object, just so it can be used in a different context, adds unnecessary complexity to a system. Take the example of an accessor in Ruby. I may need to give some other Class the information on how long to cook the duck and at what temperature, but do I need to give that to the pillow manufacturer who is only interested in the feathers?
Paddling away from ducks for a moment, think of the typical business and persistence layers in an application. In the persistence layer, the implementation details need to be exposed, in the business layer, they really shouldn't. In Ruby, you can't hide methods in different contexts, so you end up with cluttered interfaces -- monsters instead of ducks -- that rely on good programmer behavior to prevent tight coupling and low cohesion from creeping in (see the GRASP patterns). Instead, we want High Cohesion, i.e. all of the methods of a Class should focus on one or at most a few responsibilities.
Some will argue this is a Java-ism creeping into Ruby. I say this is just plain old-fashioned good OO design.
Technorati Tags: ruby, OOAD, GRASP patterns, Duck Typing
Topics: Best Practices, Patterns, Ruby on Rails
The Confluence of UXD and Agile
User experience design is integrated into software development and other forms of application development in order to inform feature requirements and interaction plans based upon the user's goals. The benefits associated to integrating these design principles include:
- Reducing excessive features which miss the needs of the user
- Improving the overall usability of the system
- Expediting design and development through detailed and properly conceived guidelines
- Incorporating business and marketing goals while catering to the user
Consultants lie. They tell you that software X can be developed in time Y for cost Z. That is a lie, plain and simple. The consultant has developed software before, and you know your business, but the two of you have never developed this particular piece of software before, otherwise you would be using it now instead of developing it. So, by definition, in software development you are doing something for the first time, otherwise you would be performing system integration.
This may explain why study after study finds that Software Engineering is notoriously poor at estimating, and why software projects typically run over in terms of cost and time. Enter Agile. Agile doesn't so much eliminate risk as admit that it is there. You don't bother putting together a 24 month project plan because you realize that:
- The estimate will be off my 400% or more.
- The client thinks they know what they want, but really doesn't.
- You'll know way more and make better estimates after 3 months of working on the project.
Topics: Agile Development, Best Practices, Usability, User Experience
GWT Conference: Joel Webber on Architecture Best Practices
Joel tackled a tough subject, IMHO. Talking about architecture in the absence of a concrete application that you want to convert to GWT (and that's what most of the folks here are looking to do), you end up giving fairly general prescriptions and best practices. The areas of focus were:
- data model (consider client and server state carefully and how to synchronize them, embrace asynchronous communication)
- application structure (break up large -- huge! -- apps, one module per page, work the single pages into the history stack, )
- browser history (not doing history breaks user's expectations of a webapp; define what a location is for your app and how state is represented; tokenize it and use GWT's history mechanism)
- simplify your server (make it stateless wherever possible, then you can scale)
- authentication (we didn't get to this)
Billy Hoffman called Joel out on the state to the client stuff and the security holes it opens. The response: be careful what state you put on the client, but much of the session state doesn't really need to be in the session. Given the audience response that followed, I think Billy can start printing money.
All in all, it seems that best practices for GWT applications are still evolving.
Some more Joel quotes:
"We used to call this DHTML, but it has a fancy new name, so we call it Ajax."
"Apparently no one can agree on what a controller is and will argue all day. What's important is that you have a model and a view and those are distinct."
"Once you understand that data updates are asynchronous, you start to think about your application in a different way, that you will get events and data updates in an unpredictable order. You just have to draw out what all the possible states have to be."
"When you move all of your session state into the client, it is usually possible to have essentially stateless servers. A stateless server gives you free scalability. However I can't help you with your database."
Topics: Best Practices, GWT
Plug: Designing Invisible Interfaces Webinar
My colleagues Matt Nolker and Shalom Sandalow have put together a nice little webinar entitled "This Won’t Hurt a Bit": Designing the Invisible Interface.. For those of us writing Web 2.0 applications, there are some key insights here, such as: "interacting with the software is not the primary goal or responsibility of the user." So when you use those nifty Ajax widgets, think about whether you are placing a usability burden on the user or are using the power of Ajax to make the interface disappear.
Technorati Tags: uxd, webinar, invisible interfaces, usability
About Pathfinder
Recent
- Roles Testing For Security
- Blackbird takes the pain out of JavaScript logging
- Making GWT JSON not Quite so Painful
- IDEA - preconference workshop 06 Oct 08
- HTML5, Ajax history management, and The Ajax Experience 2008 Boston
- A Look Back At Past Posts
- Flash Player on iPhone gossip
- Microsoft to Jump on Board EC2
- TAE Boston 2008: The Unsexy Presentations
- The Ajax Experience 2008: Hope to see you in Beantown
Archives
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
- June 2007
- May 2007
- April 2007
- March 2007
- February 2007
- January 2007
- December 2006
- November 2006
- October 2006
- September 2006
- August 2006
- July 2006
- June 2006
- May 2006
- April 2006
- March 2006


