Wednesday, October 31, 2007

Sanity Check: Language Shouldn't Matter

I've been thinking a lot lately about what makes a software project successful. Some of my co-workers at Praeses are fond of discussing the struggles of a certain Ruby project. Since it is certainly a struggling project, and since most projects at Praeses are done in C#, the culprit, the reason for the problems, must be Ruby. Obviously this is a bad assertion, but my question runs a little deeper. "What is the problem?" (or in the case of this project, "What are the problems?"

Patterns & Languages

There is such a divide out there between the religious camps of Rails, J2EE and ASP.net.

The Rails group seeks programming Zen. Clean code = happy code. Tests = happy project goodness. I've talked about Elegant code in Ruby so much that the word "Elegant" has been permanently etched into a list on a whiteboard somewhere as a word that has been banned. It is not allowed to be used any more. I have killed it.

The C# folk get a sense of security from C#'s solid foundation, it's giant class library, and the fact that it compiles to something that runs really fast. Plus it integrates so easily with SQL Server and other well-designed MS stuff. Type-safe languages can give you a really fulfilling sense of security, and some great intelli-sense.

I haven't programmed in Java, but I imagine that there code is probably an amalgamation of both. I've heard it's a little cleaner, and that there are many fun libraries.

But the thing is, and people who only work in one language will never admit this, they all work. There isn't much you can do in one language that you can't do in the others. Some code is cleaner, some code runs faster, some things are easier in one language or the other.

What really matters is the patterns.

"Good judgment comes from experience, and often experience comes from bad judgment."
Here's the thing: Stuff that didn't work well last time has a better-than-average chance of continuing not to work well in the future. Things that worked well previously stand a really decent chance of working well again.

Favor composition over Inheritance. Live the Mantra of Separation of Concerns. Dependency Injection reduces Spaghetti. Unit Tests lead to Confidence. These things are much more relevant to whether projects will fail than what language(s) they use.

Embrace Religions Tolerance! Look at the Patterns!

Tuesday, October 23, 2007

Implementing User Stories

This is a continuation of the user stories post.

User Story Cards

User Story Cards are created during meetings of the stakeholders to create the specifications for a program. Picking a specific Episode, we ask stakeholders to describe the users' experience in that episode. Each user story gets hand-written on its own index card and placed in the middle of a conference table. Although this seems existential, the physical existence of the card apparently helps to keep everyone engaged in the process.

Once there is a critical mass of stories, the cards should be sorted by importance to the client. Again, having actual index cards keeps the users engaged. Sort them from left to right in terms of priority. The most important cards will be coded first.

Acceptance Tests

Once the cards are in order of priority, we start with the first card and ask, "How will you know when this is done?" Acceptance Tests follow. These may include sentences, diagrams, drawings, etc. These get written on back of the notecards and stapled together if they don't all fit on the back. Five or so notecards means the card needs to be broken down.

An example would probably be the best way to explain this.

Story:

  • As a retail website customer, I would like to be able to delete items out of my shopping cart so that I can check out with only the items I want.

Acceptance Tests:

  • A delete box is displayed next to each item in the shopcart.
  • An ‘update cart’ button is at the bottom of the list.
  • If the user marks the delete box for one or more items and clicks the ‘update cart’ button, a window pops up giving the user the option to delete or move the item(s) to his wishlist. This popup window also has a cancel button.
Other possible acceptance tests:

- employee model
- department model
- An employee must have a first name and a last name
- employees have many departments
- departments have one manager, who is an employee
- There is a queue of unopened cases.
- The next case is determined by creation date.

By looking at a very discrete piece of functionality, the stakeholders can create a relatively complete set of functional requirements with little chance of going on too much of a tangent.

Acceptance Tests may also be referred to as Functional Tests. The name Acceptance Tests was chosen to better reflect the idea that some may be aesthetic, etc.

Test Plans

Acceptance Tests drive Test Plans. Tests plans are probably too fine-grained to be developed during a stakeholder meeting, but should be available for review by all stakeholders. Test plans should include both automated and live-tests.

Continuing the example above:

Story:

  • As a retail website customer, I would like to be able to delete items out of my shopping cart so that I can check out with only the items I want.

Acceptance Tests:

  • A delete box is displayed next to each item in the shopcart.
  • An ‘update cart’ button is at the bottom of the list.
  • If the user marks the delete box for one or more items and clicks the ‘update cart’ button, a window pops up giving the user the option to delete or move the item(s) to his wishlist. This popup window also has a cancel button
Live Tests:
  • Click the update cart button without checking any items. Should refresh the page.
  • Delete one item. Verify it is gone from the cart and not in the wishlist.
  • Move one item to the wishlist. Verify it is there and no longer displayed in the cart.
  • Delete all the items. The "keep shopping" button should appear.
  • (and so on – you get the idea).
Automated Tests:
  • item_can_be_removed_from_well_populated_cart
  • balance_is_correct_after_removing_item_from_cart
  • item_count_is_correct_after_removing_item_from_cart
  • after_removing_only_item_in_cart_cart_is_empty
Automated Tests

Anyone who has seriously embraced test driven development knows it is one of the most effective ways to create a solid application -- that is, code that does what it is supposed to do without seemingly-random "quirks". I have also found that I develop faster by writing test code than by not doing it, because it's easier to identify the end. Finally, if functionality it does break, the team will know about it before the software go to Beta.

As mentioned above, this hierarchical system takes the guess work out of writing tests. Your automated tests should cover all your acceptance tests. Although the logic of the test might be too technical, the specification should include the test cases from the live tests AND the test cases from the automated tests.

The process: Write a test. Verify that the test fails. Create the code. Verify that it passes. Beautiful. Next.

function employee_must_have_a_first_name()
{
Employee e = new Employee();
e.last_name = "Jake";
e.favorite_color = "Red";
Assert.false( e.save );
e.first_name = "Jim";
Assert.true( e.save );
}

function employee_must_have_a_last_name()
{
Employee e = new Employee();
e.first_name = "Jake";
e.favorite_color = "Green";
Assert.False( e.save );
e.last_name = "Wright";
Assert.True( e.save );
}

Domain Driven Design (DDD)

Everyone who has been involved in a large-scale development project, or has any kind of life, inherently knows about Domain specific languages. I knew about them. But until someone pointed out to me that they existed, I hadn't thought specifically about them. So, I was excited to hear it being talked about at the Alt.NET conference, because I really like thinking about things.

Sometimes it's best to talk about things out loud (and or blog about them) to solidify / unify / advance our thought process about core ideas.

From DomainDrivenDesign.org:

Over the last decade or two, a philosophy has developed as an undercurrent in the object community. The premise of domain-driven design is two-fold:

  • For most software projects, the primary focus should be on the domain and domain logic; and
  • Complex domain designs should be based on a model.
Domain-driven design is not a technology or a methodology. It is a way of thinking and a set of priorities, aimed at accelerating software projects that have to deal with complicated domains.
The premise should be so should be so ingrained and core-value to a developer that I'm not sure it deserves its own acronym.

Every stakeholder in the application must be using the same language.
example by story

Half of the developers and most of the staff think that a time entry is a group of blocks of time that start when an employee starts their shift, continues through any breaks, and ends when an employee leaves an assigned shift. Some of those blocks will not count toward being paid, others will count. Other developers think that a new time entry starts when someone gets back from lunch.

Corolary: There will be bugs. They will be convoluted to define, test for, and resolve.
The set of all named user types, resources, processes, models, etc., for a project is the Domain. Not having a common language can obviously be the root of massive miscommunication issues.

Here are two domain-specific languages I've experienced, and some of their associated terms. Obviuosly, these words may have meanings outside the domain. Inside the domain, the meanings were specific, uniform, pervasive, and integral to everything we did.

E Commerce
sale, customer, invoice, receipt, product, category, rating, review, specifications, warranty, catalog, store, drop-shipping, policy, cross-selling, up-selling, attributes, trust-driven, real estate, suggestion-driven, manufacturer-driven, value-driven, and some curse words.

Dog Agility
jump height, hight class, weaves, faults, novice, title, waved-off, touch zone, zoomies, premium, breed, Q

There is more to DDD, but that is the scope of my understanding.

References:

My blog entry on User Stories as explained to me, thunk upon, and re-explained, all within the context of DDD.

Domain Driven Design ( I love the .org TLD. It makes the site seem friendly and peace-loving... that deserves a blog entry. )

Thursday, October 18, 2007

User Stories

At the Alt.NET conference in Austin, I was fortunate enough to hear about the idea of generating user stories. Although this was entirely new to me, it was immediately clearthat this was a very effective way to create a spec. It also provides a very convenient and organized way to create functional requirements and test plans.

The concept of user stories was laid out within the context of Domain Driven Design (DDD). I don't think user stories could be effective without a pervasive domain-specific vocabulary.

Overview

The process of developing specifications using user stories is simple. We're break down a project hierarchically. These stories are the central source of knowledge about the application and should be available to all stakeholders for review / validation. No one stakeholder should make changes without buy-in from the other stakeholders.

Here is the basic hierarchy:

Projects have Epics. Epics have Episodes. Episodes have User Stories. User Stories have Functional Requirements. Functional Requirements dictate Test Plans.

This is a tree structure. If you have a test plan that doesn't fit a functional requirement, either it is an invalid test or there is a functional requirement missing. If you have a functional requirement without a user story, again, something has gone wrong. This works all the way up to a signal root node.

Epics

An Epic is a main functionality of the software. Sometimes, these are called modules. If you were writing software to manage a hospital, an Epic might be Payroll. Another might be Patient Care. These can share some domain information, like nurses and patients, but will not share others, like Job Type, Employment Date, etc.

Episodes

Episode is a subset of an Epic. If an Epic is Payroll, an Episode might be Employee Maintenance, Vacations, etc., etc. If an Episode "feels" too big, it should be broken down.

[UPDATE: Just found my notes from alt.net -- they were using the word "themes" instead of "episodes". It's arbitrary; run with it.]

User Stories

A user story should describe a specific experience of a person using the application. It should take the form of a sentence with three sections:

As a ______________ ( type of user )
I want to _____________ ( some action )
so that ________________. ( business value )

From the discussion in which I participated, it was clear that this format was great a promoting good communication between all stakeholders. By limiting the scope to a single experience at a time, it also decreases the need for changes later. User stories should make heavy use of domains-specific languages.

The scope must be kept in check: It should be a bite-size chunk of functionality, taking no more than 20 hours to develop.

Examples of user stories:
As a case worker, I need to pull the next case out of my queue so that I can mark it as being worked and add information to it.

As a customer, I need to be able to enter my personal information so that the company can search for my account or contact me.

As a company executive, I need to see daily reports on employee productivity so that I can manage the company's resources and my clients' expectations.
About Vocabulary

Be sure to use domains-specific words at every level of this process. This includes User Stories, Acceptance Tests, and the names of your test cases. Remember, this is about users' experiences, not code. The code is based on the experience, not the other way around. The following words are banned: null, table, validate, error, loop, id (there may be more.) By avoiding these technical words in your specifications, you invite the participation of every stakeholders. The word Model is allowed. Apparently non-technical people understand that things can be modeled.

References

Here is Scott Bellware's brain-dump about User Stories. Scott works at Dovetail Software, which was "500 feet" from the conference. We visited their office after discussing user stories and saw their notecards neatly organized on the board. I've got some pictures of that somewhere... Scott, do you seriously need a 40 inch monitor?

Conclusions

This is a powerful, efficient way to create a specification, to keep your stakeholders engaged in your project and its development, to build a consensus when the stakeholders have disagreements and to ensure that communication is at a maximum.

Implementation Idea for Online Help

About a year ago, I was tasked with creating a help system. I sat down, ready to pour out my astounding wit into a document that would enable users to achieve the path to enlightenment. Unfortunately, I came to as realization. I realized that I didn't know what the end users would want to know. After talking to some other developers and cogitating, I've come up with what I think is a great help system for a website. It has these goals:
  • Context Sensitive. Tells you what you need to know when you need to know it.
  • Intelligently display the most useful (used) information
  • Make it convenient for users to find/read and authors to add/update
  • Easy to Implement
Enabling Users

Your users are a lot more familiar with what confuses them than you are. If your help document doesn't cover their needs, allow them to submit questions. Also allow competent users to answer those questions. In addition to providing users with relevant help, you're encouraging a sense of community around your software.

Given the varying levels of user sophistication, grammar, organization and technical writing skills, I think a WIKI format might be the wrong idea here. However, going with something like php.net's "Add a comment" format would be very easy to implement, easy to review, and would allow users to post notes about what confused them.

Remember, no one actually clicks "Help."

Never may be a bit strong, but a "help" button is essentially putting your users farther away from information they need. Sure, the thick manual really helps to sell the software to big companies; but realistically, no one clicks that button. My preference is to add a sidebar to every page with an "About this page" link followed by the top 5 or 10 most viewed or recent Q&A-style topics. This is another opportunity to integrate user-created help by using "New" and "Unanswerd" flags.

Data Mining

One of the biggest benefits of user-generated content is that you can review it. These are actual issues being faced by customers -- not stuff that confused a technical writer. Use this content to understand your users. How are they using your software? Have they found unexpected processes that you can simplify? This sort of reasoning is dangerous because it can lead to better software, and a happiness-feedback-loop is created.Creating great help systems isn't easy, and it isn't cheap. However, this is one of the best ways to increase your returning-user-base over time, because confused users are former users.

Influences

My ideas about help documentation are heavily influenced by PHP's website. It has the best API I've ever seen. Hands down. Yes, Microsoft's implementation may be more comprehensive, but php.net's is more helpful in terms of actually finding what you need. Three reasons this site is excellent are (a) simple examples of code in use (b) great search tools (c) user contributed comments like, "Hey, if you're having this problem, here is the solution."

Wednesday, October 17, 2007

What Content Belongs in Help Documentation

It is always tempting to start to create help by opening word and typing, “The employee information screen is used for creating, reading, updating and deleting Employee information. Here is a screen shot, which hopefully looks like the site you're visiting. Otherwise, something has gone wrong.”

Since the entire functionally of this screen is so blatantly obvious to developers, it’s hard to go any other way. Here are a few guidelines for creating more useful documentation:

Recognize and explain the scope of the screen
“The Employee Information screen gives you a single point to manage all the information about an employee.”
Be sure to mention the implications of a screen
“Changing the information here will affect an employees’ information anywhere it appears in the system.”
Provide Examples
“For instance, if you change an employees name on this screen, the new name will appear on all future time sheets, their welcome screen, etc. This change will happen immediately.”
Provide information about permissions / security / auditing
“Users are limited to viewing only employees that are relevant to them. For instance, only the payroll administrators group and Executive Team group can create, read, update and terminate all information about all employees. Department heads can see a limited amount of information about only the employees they manage. There are other rules, and they may be specific to your company.”
Q&A
Once you've covered the basics, it may be awkward to add a whole bunch of small details you think might be helpful into a paragraph format. Just go straight into a Q&A section. This can be taken to the next level by making it dynamic so users can actually post questions.
Still confused?

You aren't going to have all the information they need. Tell your users what to do if they are still confused. This can take the form of further reading links and/or a contact form.
For more information see:
  • Section Title
  • Other Pages
  • Stuff Here
Still confused? Ask your question here. We’ll email you and update this document.

- or -

“See your payroll administrator for more information.”

- or -

“Contact us at (800) HELP-YOU and reference the Employee Information Help Screen”

- or -

“Click Here to email us.”
Visual Aids

A picture can be worth a thousand words. Or none.

Some people love to put screen shots in their help documentation. Just like using Power Point for presentations, this tool must be used carefully. Are you actually adding value but putting a screen shot? A rule of thumb: If you're not having to draw on your screen shot to point something out, it's probably just wasting space. Remember: Your users already have a screen shot. It's called your application.

Having covered the essentials above, write as little else as possible in the "About this page" section. For instance, I am against describing / explaining validations. They should already be self explanatory. Plus, NO ONE is going to remember to change the help when you suddenly aren't requiring the middle initial any more, and suddenly your help is out-of-date.

Monday, October 15, 2007

Perception, Distractions, Alt.Net

What's in a name? Would a rose by any other name smell as sweet? Can we move on to discussing coding, please?

At the alt.net conference in Austin, there was quite a bit of discussion about the name alt.net. Most of this was a semantic discussion of the definition and connotation / denotation of the words alternative and alternate. Does the term indicate that we are embracing alt.net while being willing to look outside the Microsoft-centric universe for tools and practices? Or does this bifurcate the community into those who follow some unspecified set of best practices and those that don't? What about those who use one or two tools but not others? Will people not like us because of the alternative aspect of this stuff?

This then becomes a branding issue. How is the word alternate being perceived by those outside the group? Everyone knows the expression "don't judge a book by its cover." The reason that expression exists is because people are hard-wired to judge books by their covers. It's human nature. Will people who aren't involved in this right now, who would otherwise benefit from becoming engaged in this discussion, stay away because of their perception of the name? Unfortunately, perception is often reality. I do think some people, who are not me, will be turned off by the name and will allow the name to inform their understanding of the goals of the collective.

If this is something that we want to spread, and I think that it is, then we need to divest ourselves of the distraction. That way, we can spread the good news that using best practices can make your life easier, less stressful and fun.

The name isn't the core of this thing we call Alt.Net. A name was needed for a group of people to associate themselves with a movement toward better development. The topic of the name, or anything that falls under the discussion of branding, should be secondary to actual discussion of practices.

I vote that the name alt.net should be retired. Frankly, anything that doesn't distract from the message would be fine with me. I would be open to calling it Jedi Programming Tricks, but it's not as flashy as alt.net.

One suggestion that I thought was positive was CodeBetter.net and CodeBetterConf. It is simple, it captures my understanding of the collective mentality, and I don't think it will be the distraction that alt.net has become.

Wednesday, October 3, 2007

The Best Way to Make It More Complicated

The project is large. Its scope seems monumental. Decisions are made with the best of intentions. This will make things easier / better / more efficient. Time is the great unit test. Implications are felt. Things snowball. The path becomes wearisome. Investments have been made. Goldberg-style fixes are implemented. Let's just get through this.

Someone suggests a change. Sometimes, in the midst of a journey, it is not time to turn around and go the other way. Sometimes, you must grin and try to cross the mountainous path because going back, although it seems like a more pleasant route, is traveling in the wrong direction.

Then there are rare opportunities to make good decisions.

Let's make the most of them. Wait for those opportunities, then ACT.