A few Virtual Brown Bag’s ago, we’ve decided to talk about Domain-Driven Design, since that was top-most voted topic suggested by attendees. From there we ended up getting to Command-Query Responsibility Segregation (CQRS), and when we get there, there’s no way not to mention either Udi Dahan’s or Greg Young’s thoughts on it.
I first saw Greg presenting about CQRS at DevTeach one or two years ago. Then I saw Udi’s presentation at TechEd Europe last year. I’ve also listened to the interview with Greg on Herding Code (twice), and I recommended you do too!
In fact, I recommend you check out what those guys have to say in the resources I’ve linked to in this post, because they’re a lot more knowledgeable on these things than I am. In this post I’ll just babble about things I have been thinking around this area.
It’s 2010 already… Wake up!
We are still doing several things in software the way we used to do 20 years ago. That has got to stop! The other day, one of my twitter buddies said something along these lines: “…trying to explain to my 8-year old son what a floppy disk is as I tell him which one is the Save button…”.
Why do we still use floppy disks as an icon for Save buttons? I haven’t personally seen a floppy disk in several years. My 10-year old daughter has never seen one. Several non-computer savvy people might have seen one of those years ago, but didn’t even know what they were.
I’ve noticed that the Drawing Pad app on the iPad uses a USB plug image. Is that better?
Well, I guess so; most people using computers nowadays are likely to have used “pen drives” to copy some data around, I guess.
On the flip side, I’ve noticed that GMail doesn’t even have a “save” button when a “contact” is being edited. I suppose that makes sense: why do I have to explicitly push a “save” button? Any app could just save stuff in the background as I work. If there’s any problem with the data (such as a business rule violation), then it could just tell me. Evernote also works like that: no need to push any button to save anything, I’ve never lost any data, and I can always find whatever I’m looking for.
Most Applications Don’t Really Represent the “Real World”
Software applications are supposed to automate and make easier things that we do in the so-called “Real World”. Most applications fail miserably at that.
Let’s think about what we do in real life when we’re “creating data” with pen and paper. For instance, maybe we’re filling out an expense report. Once we’re done, we don’t have an action for “saving” that data. The form may just sit there at our desk, until we take it to the person who’s responsible for collecting those reports.
Isn’t that similar to “saving the data”? I don’t think so.
I think something like “submit expenses for reimbursement” would be a lot more appropriate (provided that’s what the actual business workflow calls for when paying out reimbursements). Or maybe, if you’re unsure as to whether you’ve provided the correct data in the form, you may want to “submit expenses for review”, which may pipe your data through a different workflow.
In real life, do people validate your forms as you’re filling them out, or when you submit it to the person responsible for collecting it? It’s usually the latter. The form may have initial constraints for validation, though (“if you responded yes on question X, please provided some extra Y information”), in order to optimize the flow.
Once the form has been submitted, it may undergo different levels of validation, depending on how the data is going to be used. Again, it depends on the workflow.
So, bottom line regarding “save” is: applications should allow the user to create data, and decide what to do with it. The user may decide “hey, I’m not done yet… just hold on to it for me here, I’ll come back to it later with more details, and then I’ll send it to whoever or wherever I should when appropriate”.
Oh, But This Grid Can Handle Millions of Rows!!
I see people getting all excited about how this 3rd party grid or that other one is capable of showing millions of rows. Why the heck would a user need that number of rows on a grid?! The user probably needs to scroll through all that data in order to find what he’s looking for.
Then the developer thinks “yeah, but this grid makes it very easy to set visual alerts so the user can spot those rows he’s interested in”. Why not tailor the app so to allow the user to ask questions and have answers provided? In other words, when a user goes to a screen in an app, the intent isn’t something like “I want to see as many rows as it’s possible”. Instead, the user is often looking for specific data to make some decisions.
Maybe the user has the following task at hand: “hey, I need to send out a thank you card to all customers whose birthday is within the next month, but only for those customers don’t owe us money”. The app should simply offer a “send out thank you card” option. No need for grids with millions of rows.
“So what about editable grids?”, one might ask. After all, those grids are all about allowing the user to perform blazing fast data entry, right? Hmm, nope. Hardly ever have I seen a situation where the user goes cell by cell, row by row, changing data as she tabs her way through the entire grid. When a user wants to edit data, she normally has a very specific set of data that needs to be edited: “several customers have changed their number of dependents”, “the area code has changed from 123 to 987 on phone numbers for all customers in zip code 98765”. Why not allow the user to express her intent and have the app produce the UI that best fits for fast data entry based on that?
Grids have traditionally sucked at allowing for “in-place” edit. It usually takes quite a bit of work to get the hosted controls (DatePickers, DropDowns, etc.) to work well. Why go through all that pain? Why not just give the user a UI tailored to each task that needs to be accomplished?
Have You Ever Been Deleted?
We have taught users to “delete” stuff, and now they want to delete anything in a way that makes no sense at all when compared to the real world. Users want to “delete employee”, “delete product”, etc.
Have you ever had an employer walk to you and say “you have been deleted!”? Probably not. Employees are “fired”, “transferred to another branch of the company”, etc. If somebody simply “deletes” an employee from the system, nobody other than the user (who may end up forgetting) will know the reason why the employee doesn’t exist in the system anymore. Udi Dahan has a great post about this. You should read it.
Earth: from Flat, to Round, to Tabular
The client says: “My customers come to my web store and place orders for some of our products”. Several developers barely hear the end of that sentence and are already thinking “yeah, I’ll have a customers table, with a primary key, with fields to store first name and last name, and an orders table with a foreign key that links an order back to a customer, and it’ll also have an order items table, which in turn has a foreign key linking it back to the orders table. The order items table also has a foreign key that links an item to a row in my products table….”.
Most developers tend to design the application with the database in mind, as if the world was tabular, and that design bleeds through the objects in the application, all the way up to the UI. Creating UI’s modeled after a database… that’s why users think of “deleting” an employee, as opposed to “firing” an employee. We need to stop doing that.
Think of another example: the “employee screen” has a “salary” field. The user may go in there and change it. Easy. But what about the intent? Why does the user want to change the salary? There’s probably several reasons for that:
- maybe the employee has been promoted;
- maybe he is now working only part-time;
- maybe the salary was entered incorrectly originally and the user needs to fix it.
Whatever the case might be, there could be lots of things that should happen when the value changes:
- maybe an email should be sent to both the employee and his manager;
- maybe the payroll system needs to be updated;
- maybe the accountant has to be informed.
These things shouldn’t be conveyed to the user simply by providing her a TextBox with the employee’s salary on it.
Another typical case of a UI built driven by the database design is any screen with lots of “enabled/disabled” type of logic (“if this checkbox is checked, and that date is greater than X, and the sun and the moon… blah blah blah, then that control should be disabled”).
Several years ago I’ve worked in an application where there was a form with well over 50 controls, several of them being checkboxes, and there was some crazy enabled/disabled logic there. Every single developer on the team had worked on that screen, and everybody hated doing so, since even the smallest change could break behavior. Funny thing is that controls were grouped together in the UI, conveying some sort of workflow. So why did we have to stick everything into a single form, instead of creating simpler, task-oriented forms?
Let me know your thoughts on all of this. I’ll sure have more posts on this subject.