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.


Continue reading "800 on Your Math SAT, Software Development and Bugs" »

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.

Continue reading "The User Interface is the Root of All Evil" »

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.

Continue reading "Ajax Testing: Doubling Down with Selenium and JMeter" »

Stop, Reload, Error Loading Page 404: Converting Web 1.0 to 2.0

404 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.

Continue reading "Stop, Reload, Error Loading Page 404: Converting Web 1.0 to 2.0" »

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:

  1. 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.
  2. 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.
  3. 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?

Continue reading "Put on Your X-Ray Specs: Converting Web 1.0 to 2.0" »

Agile Development: Pipelining

Pipeline 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: , ,

Ajax security surprises: web-aggregators, offline applications and frameworks

Ajaxsecurity

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]

Continue reading "Ajax security surprises: web-aggregators, offline applications and frameworks" »

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: , ,

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: , , ,

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

--Wikipedia


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:

  1. The estimate will be off my 400% or more.
  2. The client thinks they know what they want, but really doesn't.
  3. You'll know way more and make better estimates after 3 months of working on the project.

Continue reading "The Confluence of UXD and Agile" »

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."

Technorati Tags: ,

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: , , ,

The Importance of Pair Programming

It turns out I've been following agile principles for longer than I realized. Back in the early 90's, I was living in a grad student coop at the University of Chicago. The house manager -- a 50-year-old physics Ph.D. who handled all of the plumbing, electrical and other assorted house maintenance -- had decided to leave. In a house populated with humanists and social scientists, all eyes turned to me, the lone "scientist." I didn't bother telling them that computer "science" isn't really a science, and to top it all off, I was studying mathematical comp. sci., which meant I was a fair hand at Combinatorics, but I couldn't tell the business end of a soldering iron from a ground wire. Still, I had helped my dad install some drywall back when I was in junior high (mostly I held the drywall in place, while my dad did all the work), so I agreed to be the new house manager.

I set two conditions, however. First, I was not going to live in the house until I was 50, and second, we would have two house managers, whose terms would overlap by 6 months. An early form of pairing. As a result, I and my pair house manager did not feel as overwhelmed as we might have if each of us had been on our own. Further, we shared information, documented it and now, over 15 years after I introduced pair house managing, the coop still uses the practice to good effect.

I know I have mentioned my 4 commandments of Agile development: iterative development; pair programming; test driven development; continuous improvement. It is hard to point to a "most important" one of the commandments -- as far as I'm concerned this is really the bare minimum of what is necessary to practice good agile development -- but pair programming seems to be the one that is most often left on the cutting room floor. The excuses are endless: "we don't have enough people," "we have an odd number of developers," "we have too many tasks to pair." The list goes on and on. For anyone that has practiced pair programming, the only objection that holds water is the "odd number" one. It is hard to pair with 3 developers, and rotating pairs or three-somes don't work so well -- someone is always the odd man out. ;-)

So what does pair programming give you and why and how does it work? In their hilarious article All I really need to know about pair programming I learned in kindergarten (May 2000, Communications of the ACM, Volume 43 Issue 5), Laurie Williams and Robert Kessler describe some of the reasons for its success. First, in a survey of developers they found that overwhelming majorities of developers were more confident of their solutions and enjoyed their jobs more. Happier programmers produced better solutions, no surprise there. But the fact that stereotypically introverted developers would enjoy a more social, collaborative work environment seems counterintuitive.

According to the article, another key benefit of pair programming is the constant code review that it provides. As it turns out, developers working in pairs think of twice as many solutions and work more than twice as fast as two developers on their own. Anyone who has seen the parabola of bug fix expense in action, i.e. bugs are much more expensive to fix the further you get toward deployment, will appreciate how valuable this constant code review is.

The article goes on to describe some best practices for pair programming, couched in kindergarten term -- "share everything," "clean up your mess," "play fair," "don't hit people." One principle that I adhere to, and that the article mentions, is that it is permissible to work alone for up to 50% of the time -- "nap time." I'm not really an advocate of the "one monitor, keyboard and mouse approach," but rather prefer the shared desk model. That way you can collaborate, but are not exhausted by the constant engagement that the shared terminal forces on you.

One additional benefits of pair programming that I've observed is that developers reach their potential more quickly, i.e. they move from junior to senior to architects or leads more quickly. They learn from others (got to keep switching the pairs from iteration to iteration), they get to make decisions on design and architecture instead of taking dictation from a tech lead, and they feel empowered. No wonder they progress and learn more quickly than developers working along.

Back in the mid to late 90's when I first tried to introduce agile methods on Wall Street, pair programming was the practice that garnered the most pushback. I usually convinced skeptical managers by convincing them that developers would spend less time surfing the web. They nodded knowingly and agreed to give it a try. I got my way, but for the wrong reasons -- managers didn't trust their developers. That points out another agile principle that fits hand in glove with pair programming: trust your people. Or, as the Agile Manifesto puts it

Build projects around motivated individuals. Give them the environment and support they need, and trust them to get the job done.

These days, I have a much easier time of selling pair programming to clients, which is all to the good.


Technorati Tags: ,

Pimp my Webapp: Turning Web 1.0 into Web 2.0, Part 1

Everyone wants the Web 2.0. But how to get there, especially if you have a dowdy old Web 1.0 application? Will I have to spend the annual GDP of a smallish Central American nation on the rewrite? There are three general approaches that evolved over the last year:

  1. The Christmas Tree Approach - decorate your Web 1.0 app with Ajax widgets and simple backend JSON or XML services. Pro: doesn't require major investment. Con: app still mostly suffers from the Web 1.0 downsides -- postbacks, CRUD, etc.
  2. The Refrosting the Cake Approach - transform all of your views from HTML to JSON or XML. Develop a client side GUI that calls your applications controllers and views. Pro: doesn't require full rewrite. Con: control flow moves from server side to client side; won't take full advantage of RIA opportunities, such as direct manipulation or document-centric interfaces; really just a nice face on CRUD.
  3. The From Scratch Approach - take the opportunity to rethink your application as something other than the web equivalent of a green screen. Imagine Photoshop or Word as a traditional webapp. Pro: unencumbered by the old system. Con: costly; you may lose your way in reinventing your app.
I think approach #2, Refrosting the Cake, is actually quite appealing. You can make using that dowdy old webapp quite a bit more pleasant with a quick coat of Ajax. There was a really interesting article on this written by Brian Walsh back in July of 2006. It sort of got lost as a pure Tibco GI article, but it has much wider applicability. In it, Brian uses XStream to convert the views of a SpringMVC sample application from HTML to XML. He then uses Tibco GI to build a UI that talks to the controllers and views on the back end.

I used a similar approach to convert a dowdy old application -- mwhois -- to Web 2.0. Instead of Tibco GI, I used GWT. And instead of XML, I used JSON.

The old application looked somewhat homely...


...and suffered from the kludgey flow and heavy postbacks typical of Web 1.0. I proceded to identify the different views and converted them (via mwhois' templates) into JSON.




simple search: domain=agiledev&ext=com

{ "isAvail" : false,
"domain" : "agiledev",
"ext" : "com",
"whoisServer" : "whois.crsnic.net" }

raw record: domain=french&ext=biz&show_raw=1

{ "domain" : "french",
"ext" : "biz",
"raw" : "Domain Name: FRENCH.BIZ\nDomain ID: D2708502-BIZ\nSponsoring Registrar: COMMUNI GAL COMMUNICATIONS LTD.\nSponsoring Registrar IANA ID: 418\nDomain Status: clientTransferProhibited\nRegistrant ID: GC683CO965021\nRegistrant Name: jamil akhtar\nRegistrant Address1: Regent House\nRegistrant Address2: 24-25 Nutford Place\nRegistrant City: London\nRegistrant Postal Code: W1H 5YN\nRegistrant Country: Great Britain (UK)\nRegistrant Country Code: GB\nRegistrant Phone Number: +44.7729391052\nRegistrant Facsimile Number: +44.2075693152\nRegistrant Email: jamil@cityfinancialcorp.co.uk\nAdministrative Contact ID: GC683CO965021\nAdministrative Contact Name: jamil akhtar\nAdministrative Contact Address1: Regent House\nAdministrative Contact Address2: 24-25 Nutford Place\nAdministrative Contact City: London\nAdministrative Contact Postal Code: W1H 5YN\nAdministrative Contact Country: Great Britain (UK)\nAdministrative Contact Country Code: GB\nAdministrative Contact Phone Number: +44.7729391052\nAdministrative Contact Facsimile Number: +44.2075693152\nAdministrative Contact Email: jamil@cityfinancialcorp.co.uk\nBilling Contact ID: GC683CO965021\nBilling Contact Name: jamil akhtar\nBilling Contact Address1: Regent House\nBilling Contact Address2: 24-25 Nutford Place\nBilling Contact City: London\nBilling Contact Postal Code: W1H 5YN\nBilling Contact Country: Great Britain (UK)\nBilling Contact Country Code: GB\nBilling Contact Phone Number: +44.7729391052\nBilling Contact Facsimile Number: +44.2075693152\nBilling Contact Email: jamil@cityfinancialcorp.co.uk\nTechnical Contact ID: GC683CO965021\nTechnical Contact Name: jamil akhtar\nTechnical Contact Address1: Regent House\nTechnical Contact Address2: 24-25 Nutford Place\nTechnical Contact City: London\nTechnical Contact Postal Code: W1H 5YN\nTechnical Contact Country: Great Britain (UK)\nTechnical Contact Country Code: GB\nTechnical Contact Phone Number: +44.7729391052\nTechnical Contact Facsimile Number: +44.2075693152\nTechnical Contact Email: jamil@cityfinancialcorp.co.uk\nName Server: DNS.INTER.NET.IL\nName Server: NS.COMMUNIGAL.NET\nCreated by Registrar: COMMUNI GAL COMMUNICATIONS LTD.\nLast Updated by Registrar: COMMUNI GAL COMMUNICATIONS LTD.\nDomain Registration Date: Wed Mar 27 00:01:00 GMT 2002\nDomain Expiration Date: Wed Mar 26 23:59:59 GMT 2008\nDomain Last Updated Date: Mon Mar 12 16:25:34 GMT 2007\n\n>>>> Whois database was last updated on: Sun Oct 14 17:51:14 GMT 2007 <<<<\n\nNeuLevel, Inc., the Registry Operator for .BIZ, has collected this information\nfor the WHOIS database through an ICANN-Accredited Registrar. This information\nis provided to you for informational purposes only and is designed to assist\npersons in determining contents of a domain name registration record in the\nNeuLevel registry database. NeuLevel makes this information available to you\n\"as is\" and does not guarantee its accuracy. By submitting a WHOIS query, you\nagree that you will use this data only for lawful purposes and that, under no\ncircumstances will you use this data: (1) to allow, enable, or otherwise\nsupport the transmission of mass unsolicited, commercial advertising or\nsolicitations via direct mail, electronic mail, or by telephone; (2) in\ncontravention of any applicable data and privacy protection acts; or (3) to\nenable high volume, automated, electronic processes that apply to the registry\n(or its systems). Compilation, repackaging, dissemination, or other use of the\nWHOIS database in its entirety, or of a substantial portion thereof, is not\nallowed without NeuLevel's prior written permission. NeuLevel reserves the\nright to modify or change these conditions at any time without prior or\nsubsequent notification of any kind. By executing this query, in any manner\nwhatsoever, you agree to abide by these terms.\n\nNOTE: FAILURE TO LOCATE A RECORD IN THE WHOIS DATABASE IS NOT INDICATIVE\nOF THE AVAILABILITY OF A DOMAIN NAME.\n" }


global search: domain=agilesoftware&do_global=1

{ "domain" : "agilesoftware",
"avail" : [{ "domain":"agilesoftware","ext":"biz" },{ "domain":"agilesoftware","ext":"be" }],
"unavail" : [{ "domain":"agilesoftware","ext":"com" },{ "domain":"agilesoftware","ext":"net" },{ "domain":"agilesoftware","ext":"org" },{ "domain":"agilesoftware","ext":"co.uk" },{ "domain":"agilesoftware","ext":"info" }] }

wizard search: do_wizard=1&company=pathfinder&keyword1=uxd&keyword2=agile&ext=com

{ "whoisServer" : "whois.crsnic.net",
"avail" : [{ "domain":"pathfinderuxd","ext":"com" },{ "domain":"pathfinder-uxd","ext":"com" },{ "domain":"uxdpathfinder","ext":"com" },{ "domain":"uxd-pathfinder","ext":"com" },{ "domain":"pathfinder-agile","ext":"com" },{ "domain":"agilepathfinder","ext":"com" },{ "domain":"agile-pathfinder","ext":"com" },{ "domain":"uxdagile","ext":"com" },{ "domain":"agileuxd","ext":"com" },{ "domain":"uxd-agile","ext":"com" },{ "domain":"agile-uxd","ext":"com" }],
"unavail" : [{ "domain":"pathfinder","ext":"com" },{ "domain":"pathfinderagile","ext":"com" },{ "domain":"uxd","ext":"com" },{ "domain":"agile","ext":"com" }] }



Then I wrote a simple, tabbed interface using GWT and the MyGWT widgets and slapped the two together.



I'll have more details on the code details in part 2 of this article. For now, you can look at the old and new interfaces.

Technorati Tags: , , , , , ,

More Evil Inheritance

Tight on the heels of my article on the evils of 'extends' and Scriptaculous, Bernard Sumption, the author of Animator.js, has expounded on why he thinks it is evil and must be destroyed.

All of the pain caused by inheritance can be traced back to the fact that inheritance forces 'is-a' rather than 'has-a' relationships. If class R2Unit extends Droid, then a R2Unit is-a Droid. If class Jedi contains an instance variable of type Lightsabre, then a Jedi has-a Lightsabre.

The difference between is-a and has-a relationships is well known and a fundamental part of OOAD, but what is less well known is that almost every is-a relationship would be better off re-articulated as a has-a relationship.

As I've already pointed out, composition is to be preferred over subclassing in most cases, and that the GoF patterns are all about replacing implementation inheritance (extends) with interface inheritance (implements). Combine this with Larman's GRASP patterns, and you see that much of the thrust of OOAD is about working around the limitations of "extends."


Technorati Tags: , , ,

Scriptaculous and Why 'extends' is Evil

The extends keyword is evil—maybe not at the Charles-Manson/Vlad-the-Impaler level, but bad enough that reputable designers don't want to be seen in public with it. The Gang-of-Four Design Patterns book is, in fact, largely about replacing implementation inheritance (extends) with interface inheritance (implements).

-- Allen Holub, Holub on Patterns: Learning Design Patterns by Looking at Code

Holub can be a bit controversial in OO circles. He throws bombs like "getters and setters considered harmful." Not everyone likes or respects him, but beneath some of that hyperbolic language, he makes some good points. Some of the arguments he makes about OO in general, and Java in particular, can easily be applied to the world of JavaScript and Ajax libraries.

Take Scriptaculous and Prototype, for example. Because JavaScript is missing some of the syntactic sugar for traditional declarative OO programming, many utility libraries take as their first task the creation of functions that make creating class hierarchies much easier. With this tool in hand, like a novice Java or C++ programmer on a bender, everything is inheritance. Everything.

Now I like using Scriptaculous, but Object.extends makes far too many appearances in it for my taste. Pretty much every effect is implemented by extending Effect.Base. The only exception is Effect.Parallel, which allows you to compose two simple effects. The resulting code is somewhat messy and difficult to modify, since the design mixes two different concerns in a single object: the scheduling of the effect and the actual DOM modification that achieves the effect.

Having started the porting of Scriptaculous to GWT (GWTaculous), I was very tempted to replace inheritance with something like the Command pattern, essentially composing the scheduling part of the effect with the DOM modification part, as mentioned above.

Right now, changing Effect.Base is extremely difficult, as doing so would break all of the effects subclasses (the Fragile-Base-Class problem, as Holub calls it). A clearly defined command interface would simplify that immensely.

There is good news on the horizon, however. Some JavaScript/Ajax libraries are starting to show a little more OO sophistication. Take Ext JS. In Ext JS, the behavior of widgets and components can be modified through the composition of different objects. To have a data grid widget, for example, retrieve it's data from a file, a static JSON structure or an Ajax call, all that is necessary is to pass an appropriate object to the widget that implements a well-defined interface. No extends necessary. Nice.

So, when writing frameworks or even a large application or library in JavaScript, view extends with mistrust. Most times, there is a better (in OO terms) way.

Technorati Tags: , , ,

Agile, The Control Paradox, and the Boring Software Manifesto

I'm probably not getting the quote quite right, but supposedly at one point during the C3 payroll project where XP was created, a developer said that it was so easy to make changes to C3 that they could turn it from a payroll system to an airline scheduling system without any strain.

Okay, it's not much of a story, but the idea resonates with the core of what Agile development means: driving the cost of incremental change so low that you can handle whatever the client or customer throws at you at any point in the process.

Gaining Control

There's two parts to that statement, of course. The first is that it's great to be able to easily fix bugs and make changes to the software over time. The second is that it's even better to be on a project that you feel is under control.

This is the paradox of being Agile. Agile dispenses with many of the artifacts that traditionally symbolize control in a development process -- big requirements documents, detailed UML diagrams, long-term Gantt charts, that kind of thing. At the same time, I've never felt more in-control of the actual day-to-day work then I do when in the midst of an Agile process. By accepting the inevitability of change in a software project, Agile allows the development team a structure by which the effect of changes can be mitigated.

The Boring Software Manifesto

Several years ago, I coined the phrase The Boring Software Development Process, in response to a former employer where project management really didn't think anything was happening unless we were trying to solve seven crises simultaneously.

The manifesto goes like this:

  • Boring software projects favor tacking exciting problems, and focusing our energy on the most interesting and valuable parts by avoiding wasting time on avoidable problems.

  • Boring software projects favor automated test suites over the excitement doing all your testing at the last minute and finding bugs after the project is "done".

  • Boring software projects favor frequently integrating work from the whole team as opposed to the excitement of finding out whether you changes work well with the rest of the team after you have been working on them for six weeks.

  • Boring software projects favor always having a working, if incomplete, system over crossing our fingers and guessing whether the newest build would compile.

  • Boring software projects favor incremental design rather than spending six months crafting a UML document that is thrown out after one week of development. (I'm not exaggerating on this one, I reviewed a project that happened on)

  • Boring software projects favor understanding that requirements change over being "surprised" when late change requests come.

  • Boring software projects favor putting working, if incomplete, systems in customer hands early to get feedback as early in the cycle as possible rather than finding misunderstandings after the project is done.

I hope that wasn't too boring... Next time, something a bit more nuts and bolts.

An Event Apart: Wrap-Up

The dust has cleared from An Event Apart Chicago 2007. Now that I've gotten the basic reportage out of the way (here and here), on to the editorial page.

Three things I loved

  • The wide range of topics: Despite increasing specialization in the web-development field, jacks of all trades still dominate our industry. An Event Apart offered sessions by and for designers, information architects, writers and developers alike. The most interesting sessions were often the ones that didn't cover my own specialties. Dan Cederhom and Jason Santa Maria both tackled visual design. There was little overlap between their presentations, yet each offered up practical device for folks who have to wing it with graphical design without much formal training. Similar cross-functional advice dominated the agenda.
  • The skepticism about rules: Presenter after presenter - most especially Liz Danzico - prioritized guidelines over rules, research over dogma, and attention to one's own audience over one-size-fits-all solutions. One thing that usually distinguishes a great developer, or at least a mature one, is the ability to juggle a host of competing concerns without getting lost in the weeds. Accessibility vs. Ajax, beauty vs. usability, power users vs. Great Aunt Tilly - everything is a tradeoff. If there was on overriding message to An Event Apart, it was that we have to think deeply and often about our audience, our business and our objectives and make informed decisions.
  • The focus on end users: It should surprise nobody that the ALA folks are usability nerds, standards geeks and champions of the end user. But it was inspiring to see how the speakers translated that well-worn agenda into series of discrete, actionable tips for everyday developers. As with any complex human endeavor, web development is all about picking your battles. With a potentially limitless number of improvements that could be made to any site or application, it's easy to feel overwhelmed. Most speakers showed how simple steps could provide incremental improvements in usability, accessibility, compatibility and profitability - all without starting over at the ground level.

Three things I didn't love so much

  • The absence of concurrent sessions: Packing all 500 attendees into one room for the same 12 sessions (picture here) allowed ample cross-pollination. I'm an RIA developer, but I got the most out of the design, IA and BI sessions. Nevertheless, I longed for the ability to choose from multiple sessions, split off from my colleagues, and come back together during breaks to compare notes. It's not that any of the sessions were completely worthless. It's just that most were designed for intermediate skill levels in the same core technologies. I really didn't need to spend 15 minutes having xmlHttpRequest and getElementByID explained to me. It would have been great if some content had been pitched to masters as well as journeymen. The only way to make that work is through careful scheduling of multiple concurrent sessions.
  • The dearth of programming content: A List Apart calls itself a site "for people who make websites," but not for people who make webapps. The broad range of topics very rarely extended to the programming realm. Only one session directly tackled JavaScript, and it was at an extremely elementary level. There was nothing on Java, Ruby, Python or .Net, let alone RIAs, widgets, mash-ups, Flex, Silverlight, GWT or JavaScript libraries. I know, I know, plenty of conferences already cater to those crowds. But as a programmer, I felt shortchanged. Again, concurrent sessions could have solved this, but I'm not sure programming - client- or server-side - will ever be on the ALA crowd's agenda.
  • The lack of schmooze time: The schedule included some after-hours social events and a 90-minute lunch break each day, but I talked to lots of attendees who felt like they didn't get enough time to chat with other attendees. Other than a lonely bulletin board - and a social-networking site opened a few weeks ahead of time - there weren't a lot of structured opportunities to connect job-seekers and recruiters or peers from separate companies. Part of the problem was probably the cramped accommodations. When folks had breaks, they were too busy stretching their legs to schmooze. Still, I would have loved to see breakaway sessions aligned by job or industry categories.

Conclusions

For "people who make web sites," An Event Apart was probably a fantastic chance to hear practical advice and smart prognostication from industry leaders. For people who write client-side webapp code, it was a very good round-up of philosophies and techniques that too often get lost amidst the technical details. For pure software engineers, it probably would have been a waste of time and money.

An Event Apart Chicago: Day 2

Tuesday saw the conclusion of An Event Apart Chicago 2007, the two-day web-development conference from the folks at A List Apart. Here's my sequel to yesterday's day-one overview. I'll be back Friday with analysis and afterthoughts.

Jeremy Keith, author of "Bulletproof Ajax" and "DOM Scripting," led the day. His topic? "Be Pure. Be Vigilant. Behave," wherein he outlined the concepts behind "Hijax," the application of progressive enhancement to Ajax functionality. A staunch proponent of unobtrusive JavaScript, Keith warned against throwing web standards out the door when developing Ajax functionality. His examples demonstrated how to separate behavior from content and presentation by abandoning such outmoded techniques as the javascript: URL pseudo-protocol. His most extensive example showed how to code a graphical widget for the assignment of star ratings so that it would degrade gracefully into a standard HTML select box in less capable browsers. After discussing the difficulty of making XHR functionality play nicely with bookmarks and the back button, Keith acknowledged that his parting message - when in doubt, leave XHR out - was a bit of a copout for the author of an Ajax manual.

Next up was Luke Wroblewski, a Yahoo product designer whose resume includes work on the original Mosaic web browser. Wroblewski covered "Best Practices for Form Design" using exhaustive research from his forthcoming book on the subject. In case study after case study, he demonstrated how simple choices in the design and deployment of HTML forms - from the widths and alignment of inputs and labels to the placement and visual differentiation of cancel and submit buttons - can cut the time it takes to complete them in half. Wroblewski's most persuasive argument, however, was conceptual rather than technical. He made a powerful case that because forms are barriers between users and the things they want to do - buy your product, join your site or begin creating content - you should make them as easy to get through as possible. This central thesis added considerable weight to his many practical how-tos.

Accessibility advocate Derek Featherstone closed off the morning with "Accessibility: Lost in Translation." Featherstone looked at how markup choices can make a site transparent to assistive devices - or render it totally opaque. Using real-world examples from Amazon and other sites, he demonstrated how screen-reading software actually parses markup. His live examples proved that the lack of semantic markup and the absence of ostensibly optional HTML attributes can render a site worthless for disabled users. Featherstone then went beyond the basics, explaining how source order - the sequence in which nodes appear in your markup - can be used to enhance accessibility. By placing your central content first, then positioning chrome above it with CSS and providing jump navigation to skip past inessential modules, you can achieve the presentation you want for typical users without shortchanging disabled ones. In another example, Featherstone examined the ways in which meaning can be encoded in the color and position of elements on the page - and how to replicate that meta-data in a way that disabled users can understand. As with many of the other speakers, Featherstone's examples argued persuasively for the continuing relevance of web standards.

After lunch, CSS expert Eric Meyer again took the stage, this time to explore "The State of CSS in an IE7 World." Using the recent release of Microsoft Internet Explorer 7 as a springboard, Meyer illustrated the concepts that have governed the changing of the browser guard for more than a decade. His overall premise was that developers need to use their own server logs to gauge when support for an older browser can safely be dropped for their site. For most of us, IE6 isn't going away anytime soon, so we need to get creative if we want to harness advanced functionality. To that end, Meyer delved deeply into the details of IE7 techniques, filters and hacks. He praised the browser for the strides it makes over IE6's CSS engine in such areas as child selectors, adjacent sibling selectors and attribute selectors. His real-world examples demonstrated how such functionality adds power and elegance to our code. To cope with IE6's continuing market share, Meyer advocated the use of Dean Edwards's IE7 compatibility script, a JavaScript library that adds IE7 capabilities to older versions of the browser. The take-home message was that older browsers may take a long time to die out, but creative programming techniques can harness the future of CSS now.

The final two sessions for AEA Chicago 2007 were a little offbeat, which was a relief after 10 technical sessions in the previous 32 hours. In the highly anecdotal "Selling Design," ALA publisher Jeffrey Zeldman used stories from his own long career to illustrate best practices for handling difficult clients. His thesis was that collaborative work requires us to deal with a wide range of other people, so we should hone our ability to influence our collaborators - and pick good clients to begin with. Agency owner Jim Coudal closed things off wittily with "Dealing With the Both of You," a slide-free presentation about the crossover between personal projects and professional work-for-hire. Coudal assembled a number of satirical short films to drive home his point: Because most web developers are curious and easily bored, we should strive to marry passion with professionalism whether our clients are external or ourselves.

An Event Apart Chicago: Day 1

The folks from A List Apart rolled into town yesterday for An Event Apart Chicago 2007, a two-day web-development conference. Around 500 programmers, designers and information architects flocked to the seventh floor of the downtown Mariott for a varied slate of talks by some of the biggest names in the industry. Today and tomorrow I'll give high-level overviews of each day's sessions. On Friday, I'll provide some color commentary.

Stylesheet guru Eric Meyer's "Secrets of the CSS Jedi" kicked things off with an in-depth case study in which pure CSS 1 and 2 transformed tabular data into an Excel-style bar graph. Meyer's presentation was interesting not only for what his techniques could accomplish, but also for what they couldn't. It was inspiring to see that plain-vanilla data could be given a powerful visual makeover, yet still remain completely semantic and accessible to handicapped users. But it was disheartening to see that the simple addition of tick marks within the graph demanded the addition of hard-coded percentage values to a number of CSS classes. The lack of simple computational ability within CSS declarations has long been a drawback of the "not a programming language" language. CSS remains a powerful and flexible technology, but, as I discussed at length a few days ago, it's got a lot of room for growth. For those who were already conversant with Meyer's techniques, perhaps the most interesting digression in his talk was the chance to tear through Firefox's built-in browser stylesheets and see how even the most fundamental rules of HTML presentation - such as the invisibility of meta tags and the entire <head> block - are controlled by CSS behind the scenes. Meyer also went over the basic building blocks of the kind "reset" stylesheet most jedis use.

Up next was Jeffrey Zeldman, publisher of A List Apart and therefore another another rock star to this crowd. A lot of recent ALA content has focused on the overlooked art of writing for the web, so it was no surprise that Zeldman tackled the topic "Writing the User Interface," which packed in plenty of practical advice for writers and non-writers alike. His central thesis was that copy was the cheapest and easiest thing to improve on most sites. Using lots of witty real-world examples, he provided a useful paradigm for breaking textual content into discrete components - guide copy (a.k.a. instructional text), brand copy (taglines and other branding assets), copy copy (a.k.a. real content), labels and URLs - and applying different editing criteria to each. As befits the author of "Designing With Web Standards," Zeldman was careful to demonstrate that the rules of good web writing and the rules of semantic markup are often one and the same. As with most of Zeldman's advice over the years, he started with a compelling philosophy, then showed how to break it down into small, actionable steps.

Happy Cog designer Jason Santa Maria finished off the morning block with "Design Your Way Out of a Paper Bag," a look at the process of rebranding and redesigning an existing site. An illustrated tour of Santa Maria's own iterative design process, the presentation was, like the earlier sessions, a case study in how a series of small steps can have a big impact on the usefulness of a site. Using an amusing Flickr tour of real-life signage and the abuse and misuse of the poor apostrophe therein, the designer drove home his biggest advice: "Sweat the small stuff." Along the way, he touched on typography, branding, logo development, grid-based layout, whitespace and other design concerns. As befits a designer, Santa Maria's session was probably the most visual and the least easily captured in the PDF slides distributed to attendees. He did, however, suggest some excellent further reading, most notably "The Elements of Typographic Style," "Thinking With Type," "Grid Systems" and "Making and Breaking the Grid."

After lunch, Lou Rosenfeld led with "Search Analytics For Fun and Profit." In a series of painstaking real-world case studies - most notably of my alma mater Michigan State University - Rosenfeld explained how server logs and especially search engine logs offer the keys to a successful site redesign. It's a simple idea that may seem elementary to many developers, but given how infrequently web-development teams actually use this feedback loop effectively, Rosenfeld's techniques struck me as really powerful. You would expect a session like this to show you how users' most popular search terms could serve as the springboard to an overhaul of your navigational systems. But Rosenfeld also delved several levels deeper, showing how much powerful business intelligence can be obtained from inexpensive tools with little or no custom code to support them. Site indices, metadata, search algorithms and the search interface itself - all can be tweaked based the subtle metrics that emerge from careful, detailed session analysis.

Perhaps the most inspiring session was Liz Danzico's "The Seven Lies of Information Architecture," in which the Happy Cog information architect recast the high commandments of IA as guidelines rather than rules. Danzico used copious examples to demonstrate how the most successful sites often bend or break the supposedly unwavering rules of IA. The idea of the magic number - most users can only remember 7 +/- 2 items in their short-term memory at any given time - was the first concept to show cracks under Danzico's microscope. She went on to debunk the holy status of such maxims as "consistency is good," "navigation is necessary," "the shortest path is the best path," "experience must be seamless" and "users should always know where they are." Sometimes, the idiosyncratic nature of her examples suggested that certain guidelines work for most sites and are best broken only for a specific purpose. Other times, especially in her examination of Amazon's and Apple's navigational systems, her case studies suggested that even mainstream sites do and should break the rules. It was Danzico's last rule - the idea that only IAs should do IA work - that she most thoroughly debunked by the end of her session. She argued passionately that site owners, designers, programmers and end users can and should understand the guidelines of information architecture - but, like IAs themselves, they should apply those guidelines judiciously rather than rigidly.

Last up was designer Dan Cederholm, founder of SimpleBits and Cork'd. He constructed an elaborate site prototype, ToupeePal, to demonstrate "Interface Design Juggling," his thesis that great design involves keeping lots of balls in the air at the same time. Delving deeply into typography, microformats and the development of favicons, Cederholm demonstrated that beautiful and useful interfaces can be constructed using the supposedly unsophisticated visual and informational tools already at our disposal. Cederholm cried foul on the idea that web typography sucks because too few cross-platform fonts are available. He argued that the single-font typography of the Itallian Renaissance is some of the most beautiful ever created, then he demonstrated practical techniques for getting similar mileage out of limited existing web fonts. Word-spacing, letter-spacing, line-spacing, color, weight, italicization and other simple tools can all elevate even the most familiar typefaces into the design stratosphere. Likewise, even a tiny 16x16-pixel favicon can provide a powerful branding tool when designed correctly. Cederholm closed with an in-depth look at the "accidental API" of microformats, demonstrating that a even a grassroots open-source movement can add power and value to the web without the support of standards bodies and browser vendors.

Check back tomorrow for coverage of today's sessions, from Eric Meyer's look at the post-IE7 world to Derek Featherstone's talk on accessibility.

That's so 1999

Lots of trees (and pixels) have given their lives over the past 10 or 12 years to fuel the endless debate about graceful degradation, progressive enhancement and the separation of style and behavior from content. The web standards movement has gained traction by boiling the argument down to one simple assertion that geeks can sell to suits:

If you're in the business of hawking something - vintage hockey memorabilia, advertising impressions, "Harry Potter and the Deathly Hallows" or even plain old editorial content - then you should probably build web sites that make it as easy as possible for as many people as possible to give you their money...

... even people who can't or won't enable JavaScript in their browser/phone/whatever.

It astounds me that we still have to belabor this point in 2007. But a random sampling of large commercial websites reveals that even the big players haven't yet taken this lesson to heart. United Airlines, Sears, Expedia and Amtrak, for example, fail in various subtle or spectacular ways when you disable JavaScript or employ a user-agent without it.

(If you're using Firefox, just install the Web Developer Toolbar, use the Disable menu to turn off all JavaScript, and load one of these sites.)

When you load United's new(ish) multimillion-dollar booking engine sans JS, you get a search form with empty date dropdowns and a bunch of links and buttons that don't work. Sears.com is even more insidious. With a little bit of work, you can get some products into your cart. But when you click the checkout button, nothing happens.

Once upon a time, most commercial sites would at least use a <noscript> block or a server-side browser sniffer to warn you that their sites required JavaScript to function. That's how Amtrak does it today. So does Expedia:

Expedia1_4

"To enable great site features that are currently disabled, simply make a few adjustments to your browser settings ...." And what, pray tell, qualifies as a "great site feature"? Apparently, the ability to search for flights at all:

Expedia2_2

I can understand how a start-up like Kayak - with its innovative Ajax UI - can afford to demand a modern, scriptable browser. That will all change when they have a mature business model. But a travel behemoth like Expedia?

Look at the biggest successes of the eCommerce gold rush. Amazon, eBay, Yahoo and Google just plain work on all sorts of user-agents. Often, they offer separate interfaces optimized for mobile or assistive devices. Disable JavaScript on these sites and you can shop, search and browse to your heart's content. How can a site like Expedia not emulate them? Last time I looked, travel was a low-margin, high-volume business. Even if you're throwing away only 1 percent of your business, that's still a _lot_ of wasted revenue.

I'm also at a loss to explain how what's left of our pathetic national passenger-rail service can afford to squander potential customers by requiring them to use a technology that opens up untold security holes in the browser used by the majority of the planet.

Most places, I'm the biggest JavaScript dork in the room. I'm writing on a blog called Agile Ajax, for god's sake! But I still expect my favorite sites to work when I'm stuck on a Windows machine whose network admin has ratcheted up the security to absurd proportions. When I borrow a pal's iPhone, with its five-second script timeout, I expect to be able to do _something_ on the sites I visit. Ditto when I'm on a tediously slow connection on a laptop overseas.

I don't mean to pick on these sites. Heck, in a former life I worked for one of Expedia's competitors, and our site failures in non-JS environments were often of the silent but deadly variety. Even earlier, I was a contractor at United itself, and I'd sooner page through my junior-high yearbook than look at the still-live JavaScript code I wrote for them. Back when I was at Reflect.com, a now-defunct customized-cosmetics emporium in San Francisco, I used to generate the entire homepage with JavaScript, just because I could. I was having fun learning the language.

That was then, this is now. Jeffrey Zeldman's "Designing With Web Standards" is in its second edition. Any number of blogs, articles and books spell it out for even entry-level developers exactly how they can architect web applications that benefit from all that JavaScripty, Ajaxian goodness without turning away users who can't or won't partake.

We have the tools. We can do it. When we don't, it's a deliberate choice. The next time you're gathering requirements for a consumer eCommerce application, sit down with your client in front of a zippy new Vista PC running IE7 with JavaScript disabled via the security settings. Then try to buy some slippers from Sears, or a hotel room from Expedia, or a ticket from United. I don't think you'll have much trouble selling progressive enhancement as a fundamental part of the solution you're building.

Plug: Integrating Agile and UXD

FYI, my company has just released a whitepaper on integrating Agile Development and UXD (User Experience Design), a subject of great interest to anyone developing Ajax/Web 2.0 apps. As the complexity and sophistication of our webapps increase, we have to rise to the challenge of making them easy to use. The whitepaper is an overview of some of the best practices and ideas from our own experiences of bringing our UXD and Agile Appdev practices together. Warning: the paper is free but requires registration (i.e. an email). So, if you are easily annoyed by this sort of thing, you probably don't want to click on the link above.

Technorati Tags: ,

Agile Practices and Ajax Toolkits

I've been practicing agile development in one form or another through my involvement with open source projects since the early 90's. Of course at the time, we didn't know we were practicing Agile development. We were distributed, we had real jobs, we were pressed for time. Often we compensated by eyeballing requirements, having rapid releases, and evolving the SW over time as new needs and requirements were discovered. Now many of those shortcuts that grew out of necessity are at the core of Agile.

In all that time, I've developed my own philosophy (when you turn 40, your "opinions" turn into a "philosophy") on how Agile development should be done. There are a number of core principles I adhere to:

  1. Short iterations. Thirty days is a nice number.
  2. Pair programming (not necessarily the one keyboard, one mouse variety). Yes, two developers working on the same tasks do get more done than the same developers working on separate tasks. The practice also really boosts quality and learning.
  3. Test Driven Development. If you've ever worked on projects that don't have extensive unit and integration tests, then you've experienced the waves of bugs that appear with every new feature or enhancement. TDD -- rather than after the fact unit test development -- is also the only way to guarantee that the practice doesn't slip during stressful times.
  4. Continuous integration. Hourly is good enough. If you've worked on projects without CI, then you've felt the pain of week long "build and deployment" sessions, driven by the poor sods condemned to being the "build masters."
  5. Self organizing teams practicing continuous improvement through process reviews.

Everything else is negotiable, as far as I'm concerned. Through #5, each team will find the right agile methods and practices for themselves and the client. No single method (note, "methodology" is the study of methods) is appropriate for all situations and teams. I myself favor Scrum as a wrapper around the development process, as it incorporates #5 as a core principle.

Turning now with these Agile principles to the world of Ajax frameworks, which of them explicitly incorporate unit testing into their development? This is an important consideration, since if a framework doesn't provide unit testing facilities or hooks, you will have to develop and maintain them in step with the framework. As an example, with full unit test coverage (branch and line) in place, you can weather the release of new browser version (think IE7 and Safari for Windows) much more easily. Not only will you know that your sophisticated Ajax interface doesn't work, but you will know exactly why it doesn't work (probably).

So, which frameworks do incorporate unit tests, and how easy do they make it to hook those into your own development machinery?

  1. GWT, of course, lets you use JUnit directly.
  2. Prototype  and Scriptaculous both use the same unit test harness, which already comes integrated with Rake (Ruby make), but would take a little work to integrate with other build environments.
  3. JQuery does have unit tests that can be run with make or ant, but they aren't extensively documented, so extending them to your own development environment will require a bit of work.
  4. Of the straight Javascript frameworks, Dojo has the best documented unit testing approach, as well as a build process that can be integrated into your build environment.

(BTW, has anyone else noticed that YUI doesn't have a publicly available SVN?)

The one tricky bit with testing Javascript is that object definition and creation can be pretty complex code itself. Ideally it should be tested as well, though that doesn't always happen in the above frameworks. Whatever framework you choose, make sure that it provides unit testing facilities that your developers can and will use, otherwise your user interface will be the redheaded stepchild of your web 2.0 webapp.


Technorati Tags: , , ,

Five Ajax Anti-Patterns

This is an item from back in March, entitled Ajax and XML: Five Ajax anti-patterns. The material isn't rocket science, but every so often it is good to be reminded of how not to do Ajax.

The five anti-patterns are

  1. Polling on a timer when you don't need to
  2. Not inspecting the return results in the callback (of an XHR)
  3. Passing complex XML when HTML would be better
  4. Passing XML when you should pass JavaScript code
  5. Doing too much on the server

A useful warning on the behavior of timers, familiar to most experienced Javascript developers, but useful nonetheless:

The window.setInterval() method tells the page to call back a particular function on a particular interval -- say, every second. Most browsers talk a good game when it comes to these timers, but they rarely deliver, primarily because the JavaScript language is single threaded. If you ask for a second, you might get the callback at 1 second or 1.2 seconds or 9 seconds or any other time.

Give it a read. To be honest, I have seen a number of inappropriate uses of polling on some public web sites, so it may seem like a dope slap obvious kind of thing to me and you, but plenty of people fall for it.

Technorati : , ,

Taking Your Javascript to Bed with You, Part 1

If you read good books, when you write, good books will come out of you. -- Natalie Goldberg

I first started fiddling with Open Source software somewhere in the mid to late 80's. I was strictly a download and compile guy at the time, but Unix variants being what they were, I was soon up to my elbows in makefiles and C in order to get the darn things to work. From there it wasn't that big of a leap from hacking around to reading the code, and reading code was a truly mind expanding experience.

Up to that time I had just been reading code from books -- little toy programs designed to illustrate a point rather than for production -- and had not been exposed to all of the idioms and approaches that were out there in the wild. You have to read and write lots of bad code before you write good code. And I did plenty of that, even contributing some code here and there to early Open Source projects. I would often download code just to read, not even to compile and install. At one stage I got really into Literate Programming and wrote several large systems using this Knuth inspired approach to writing human readable code. (I found, however, that few in the business world actually value documentation, especially when the deadline clock is ticking.)

One thing is for certain: I learned an awful lot, both on what to do and not do, from reading all that Open Source code. It expanded my world from just books and the handful of programmers I worked with on a daily basis to a cummunity of hundreds and, later, thousands of talented programmers. I stole their ideas and techniques with ruthless abandon. To this day I still read Java, C# and Javascript code in the hopes of finding new ideas and idioms. I even take my code to bed with me to read it before drifting off to sleep.

One of the areas where books are pretty lousy is OO Javascript. Most of the books will let you know how to create your own classes as well as doing some basic inheritance. But beyond a few toy examples, they won't help you in writing real code. Where to look? The major Javascript libraries -- Prototype, YUI, etc. -- have a variety of approaches to OOP. My own preference is for the style adopted by YUI, very similar to that suggested here, here and here, which allows you to chain constructors. My reasons for preferring this approach? I use an excellent and cheap UML modeling program call Enterprise Architect to generate code from models. A more traditional approach to inheritance like YUI's makes writing code generating templates for EA easier.

YUI's approach is short, but not necessarily simple:

YAHOO.extend = function(subclass, superclass) {
    var f = function() {};
    f.prototype = superclass.prototype;
    subclass.prototype = new f();
    subclass.prototype.constructor = subclass;
    subclass.superclass = superclass.prototype;
    if (superclass.prototype.constructor == Object.prototype.constructor) {
        superclass.prototype.constructor = superclass;
    }
};

The punchline here is that you can now call the superclass methods and constructors from the subclass.

YAHOO.widget.SimpleDialog = function(el, userConfig) {
YAHOO.widget.SimpleDialog.superclass.constructor.call(this, el, userConfig);
};

YAHOO.extend(YAHOO.widget.SimpleDialog, YAHOO.widget.Dialog);

YAHOO.widget.SimpleDialog.prototype.initDefaultConfig = function() {
YAHOO.widget.SimpleDialog.superclass.initDefaultConfig.call(this);

// Add dialog config properties //
this.cfg.addProperty("icon", { value:"none", handler:this.configIcon, suppressEvent:true } );
this.cfg.addProperty("text", { value:"", handler:this.configText, suppressEvent:true, supercedes:["icon"] } );
};

Prototype, JQuery and company have a somewhat different approach to inheritance. There's no constructor chaining, but there are a few more ways to inheriting behavior. For example, in Prototype 1.4, the extend function copies the properties from a base object to a subclass object:

Object.extend = function(destination, source) {
  for (property in source) {
    destination[property] = source[property];
  }
  return destination;
}

It's a bit more primitive, but can be chained like so: Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype),...

The Yahoo approach to private versus public instance variables and methods is one of commenting and naming. Private instance members and methods are prefixed with a '_' except when they are not. In either case they are commented so as to identify whether the member or method is private or public. Dojo, on the other hand, makes some use of closures and inner functions to enforce the whole public/private thing (see Douglas Crockford's post on this).

One thing that is common to just about all of these frameworks is excellent documentation. Have a dynamic language like Javascript without strong typing and heavy use of idioms puts the burden on the developer to document the code, e.g. from Dojo dojo.io.setIFrameSrc = function(/*DOMNode*/ iframe, /*String*/ src, /*Boolean*/ replace).... I'm looking forward to Javascript 2 with it's support of real classes.

This just scratches the surface of what these various frameworks have to offer. Read code, make notes, save snippets, and improve your own code.

    Technorati : , ,

That Giant Sucking Sound is Ajax Turning Your Site into an Application

I have a simple rule of thumb for support costs: take the number of use cases, function points or whatever you use to estimate development effort, multiply it times the number of users who will be accessing your application, correct for the sophistication of that population -- Joe Hacker versus Grandma Moses -- and the amount of money that is on the line for both your users and your company, and voila! you have a three shift operations center and an army of developers wearing pagers. Actually, it gives you an order of magnitude figure for the kind of effort supporting your application will take.

Here it's common to distinguish between sites and applications. By sites we usually understand the simple content display where your use cases consist of browsing, search, emailing an article to a friend and viewing an article in printable form. Four use cases, give or take. Add in the occasional submission form, and your support team, such as it is, barely needs to break a sweat. Applications, if I may state the blindingly obvious, have many more use cases and thus much greater support costs.

Now at what stage does a site become an application? This is sort of like the riddle of Theseus' ship. (Theseus was the guy who slew the Cretan Minotaur.) His ship was preserved as a memorial. As planks and other wood rotted, it was replaced bit by bit until not one piece of the ship was original. Was it still the same ship? If not, at what point did it stop being the same ship? Fortunately for us, our question is not quite as hard. Ours is not a question of identity but of degree. A site doesn't magically become an application with one additional use case, it just becomes more complex. In fact, our distinction earlier between sites and applications was a false one -- a site is a simple application, with a simple purpose and simple task flows.

Now I started this post talking about support costs and ended up talking about wooden planks. My point is that as you go about replacing the rotted postback planks in your site or application with nice new pressure treated Ajax planks, keep and eye out for feature creep. Are you adding functionality to your site? Are you adding digg style voting to your content? Are you adding a portal so users can customize their experience? I'm not saying don't add them. By all means, take advantage of the opportunities the technologies give you, just be cognizant of any new features and use cases you add. You could find yourself sucked from the relatively safety of the content application -- or "site" -- to the deep water of the full on application.

When they pry the support pager from you cold, dead hands, you'll go to that Valhalla that is home to optimists, jaywalkers, chronic underestimators, and managers that think that product launch is the finish line.


Technorati : ,

Securing Ajax

Scott Dietzen over at Zimbra has an interesting blog entry on Securing Ajax. He takes a somewhat unconventional approach, starting with the security advantages of Ajax:

  • Dynamic Ajax client download - Ajax client code is downloaded on demand from the trusted server after a particular user logs-in, automatically ensuring client and server versions are in-sync (for public computers, a shift re-load is better in that it overwrites any Ajax code from that website leftover in the browser cache).
  • No persistent client caching - An exposure with traditional web clients is that they cache HTML pages that can include user/application data on the client disk during normal operation. This can be a security vulnerability for access from public kiosks or other shared computers. Ajax applications like the Zimbra client cache no user data on disk.
  • Server-side control of intranet and Internet mash-ups - Zimlets and other Ajax mash-ups are precluded from accessing arbitrary services on the Internet (unless they open a new iFrame, which can be determined at server deployment time),