Archive for January, 2008
Monday, January 28th, 2008
I'm currently recovering from the Infusion Sleepless Roadshow, where we collectively hacked SharePoint beyond recognition. I've recorded some interesting conversations, and I'll be bringing those to you very shortly. But in the mean time, let me tell you what I've learned about SharePoint.
You've probably used SharePoint as a document management system. It's a fantastic repository for Word documents. It handles organization, security, and versioning out-of-the-box. But for most organizations (including mine), that is all that SharePoint is used for: a shared folder with benefits.
What I learned this weekend is that Microsoft's vision for SharePoint is so much larger. It has a workflow engine that can track a work item through a long-running business process. It has Office integration beyond the publishing capabilities we've all used, including custom task panes and ribbons. And it has all the customizability that you need to create fantastic looking public-facing sites.
The problem is that not many people know how to do these things with SharePoint. Or, rather, that's the opportunity. This event demonstrates that it is possible to create a brand new web application overnight ... literally. And the people who can do that are in high demand.
Before the competition, we had 12 hours of intense training. During this training, one thing became quite clear. SharePoint development is not like your typical application development. You have to approach the problem from a completely different angle.
In typical application development, you'll set up a code-build-deploy cycle from the beginning. Developers will go through several small iterations of this cycle every day. A slightly longer version of the cycle pushes weekly builds to QA. And an even longer cycle promotes releases to production.
In SharePoint, many of the development artifacts are in the site itself. You add custom lists to define new data types. You build workflows directly within the site. You create web part pages in place. And finally, you package all of this up as a template.
So just like a spreadsheet where cells contain either data or functions, code artifacts are intermingled with data. It is common practice to put pages into lists, along side documents and items. Furthermore, there is no apparent difference between the list and the type of data it contains. You add columns to the list in order to define its "type". Finally, you define workflows within a site so that they have access to those columns. It is difficult to separate code from data in order to deploy.
In search of the repeatable process
I like the repeatable process of the code-build-deploy cycle. During the training, there were glimpses of this cycle when they showed Visual Studio projects that produced WSP files. There is an event that you can handle within your code to provision a site upon deployment. If used properly, I'm sure that a repeatable process could be achieved.
During the competition, however, I found that this is not easy. I wasted three hours of our precious time fighting with Visual Studio, IIS, and SharePoint to get this process to work. I finally abandoned this effort in order to help my team.
So if you remember what SharePoint is good at, you can do quite well. Don't look to SharePoint as a typical development platform. It is a place where your application can grow up gradually over time. It can get your site up and running with a very small investment, and then expand it to add more features. Maybe that's not the "right" way to develop software, but it satisfies a business need. As G. K. Chesterton famously wrote: "Anything worth doing is worth doing badly."
Thursday, January 24th, 2008
Ivar Jacobson codified Use Case Analysis in 1986 as a way of expressing functional requirements. Since that time, the technique has been improved and formalized. It is now part of the Rational Unified Process.
Why should I write use cases?
- Use Cases help the systems analyst or software designer to understand the system under construction.
- Help customers understand the system being built. Users can validate that the use cases are correct.
- Use cases are an easy to understand and interpret way of communication the functionality of a system to an implementor.
What goes into a use case?
- The name of the use case
- An identification number that will uniquely identify the use case. This number WILL NOT CHANGE, even if the use case is modified or deleted. This is important for tracking history.
- Actor - What actor or actors are going to be the focus of this use case?
- Goal - What is the end result of this use case.
- Preconditions - What must already be true about the actor or system before this use case is valid.
- Triggers - What triggers this use case? A user inserting their ATM card? The predetermined nightly batch processing time? etc.
- The Success Path - What happens when everything goes right with this use case. This description should start with the trigger and tell the story of how the state of the target system changes.
- Alternate Paths - This section talks about what can go wrong and how the system will respond to those error conditions.
- Post Conditions - This describes what state the system will be in once the use case has been executed to completion.
- Business Rules - Call out any business rules that apply to this use case. (RE: I'm not sure about this one...I got this from Wikipedia...not sure I like it)
What is the scope of a use case?
How does a use case compare to a story in agile methodologies like Scrum?
Advantages of User Stories
Do I have to choose one or the other?
Should I strive for 100% feature coverage with use cases?
As a developer, if my company doesn't perform use case analysis, can I write use cases on my own?
When you have all of your use cases, what next? (discussion about dynamic behavior running through static strcuture)
Use Case Tutorial
We've started a document template library. There you can find the Use Case template that we promised you.
Thursday, January 17th, 2008
Historic modeling is the technique of representing a solution as a history of discrete events. This differs from static modeling, which represents the solution as a snapshot. The static model is concerned with the state of the system, whereas the historic model is more concerned with how it got there.
A historic model can be represented in an Entity Fact diagram. This is analogous to the Entity Relationship diagram used in static models. The difference is that you represent historic facts instead of static relationships. Relationships can change over time, but facts are always true.
I am currently working on an automotive wireless system that provides an excellent example of an Entity Fact diagram. This system tracks wireless devices such as OnStar modules that are installed in vehicles. The entities in this domain are things like the phone number (MDN/MIN), the wireless unit, the vehicle, the customer, and the service. We can draw an ERD to represent the relationships among these entities.
In this ERD, we represent entities as rectangles, relationships as diamonds, and properties as ellipses. We are particularly concerned with the status of a wireless account (active, suspended, inactive, etc.) and the status of a wireless device (scrap, replacement, defective, etc.) The account status is a property of the relationship between phone number and device.
In this ERD, relationships can come and go. A unit can be removed from a vehicle and a replacement installed. A customer can enroll in a service, and later cancel their subscription. In a typical static model, these relationships are created and destroyed to represent the current state.
Expand to an EFD
To model the system historically, we make note of all the events that could occur. Each of these events is one fact: it occurred at some point in time. Whether the effect of that event is still present is less important. The fact is, and always will be, that it happened.
The facts in this system are things like:
- An MDN/MIN was paired with a unit.
- The MDN/MIN pairing was removed (the account was closed).
- A customer took delivery of a vehicle.
- A customer enrolled in a service for a vehicle.
- A service enrollment was canceled.
There are many others as well. Here is the complete diagram.
You'll notice that these facts usually relate two or more entities. In fact, they usually create or destroy relationships between those entities. When one fact modifies the effect of another fact, it references the original. So, for example, an Unpairing destroys the relationship established by a Pairing.
A fact cannot exist until its referenced entities exist. An MDN/MIN must be assigned by the phone company before it can be paired with the MEID of a device. Both the vehicle and the customer must exist before the customer can take delivery of the vehicle.
This prerequisite relationship is also true for facts. An MDN/MIN pairing must occur before they can be unpaired. A customer must take delivery of a vehicle before enrolling in services for that vehicle. So the arrows not only indicate references, but also define a partial order. The referenced fact must occur before the referencing fact.
Facts are either true or not. The event has either occurred or it hasn't. There is no intermediate state.
Notice the history formed by Manufacture and Replacement. A vehicle is manufactured with one unit. At some time later, that unit is replaced with another unit. The replacement destroys the vehicle-unit relationship created by the manufacture, and simultaneously creates another relationship. That replacement unit can later be replaced by yet another replacement unit, and so on.
The source of truth
This ERD is color coded to indicate the source of each of these facts. Blue facts come from the phone company, green from the device supplier, and red from the auto manufacturer. This helps us see interactions between various parties. We can see, for example, that the device supplier can't tell us that a pairing will not be used until the phone company tells us that it exists. This helps us see that we have to wait for the phone company to tell us that the number is paired before we send an unpairing request, thus avoiding a race condition.
Whether the program is written historically, an Entity Fact Diagram can help us capture important information. It is more complete than the ERD alone, as it shows all the ways in which relationships can come and go. It helps us communicate the order in which events can occur, and gives us guidance on transaction scope and system interactions.
Tuesday, January 15th, 2008
I don't know why, but elevators fascinate me. I guess it's because they represent a daily junction of people, process, and technology. They embody many of the problems we face with limited resources, queues, and traffic.
I've noticed that people tend to gather in front of doors that are about to open. It's probably preservation of your place in line so that the elevator doesn't fill up with people who haven't been waiting as long as you have.
The problem with this behavior is that the elevator is invariably filled with people wanting to get off. There is always a dance where the people trying to get out negotiate with the people trying to get in for a traffic lane. The dance lasts for about three seconds and it always ends with the people crowding around the doors retreating into the lobby to give the others a lane of egress.
Wouldn't it be better for everyone if people would stand away from the doors? You can be fairly certain, especially on the ground floor, that there are people trying to get off the elevator. There is limited space inside the car, but comparatively unlimited space in the lobby. It only makes sense to let them off first.
But people don't behave that way. The elevator represents a limited resource that they have already invested in. They have to preserve their access to that resource.
Here's my solution
Put the alert light and bell on a delay. Instead of alerting the people waiting for the elevator before the doors open, only give the indication after the people in the car have had the chance to get out.
What does this have to do with software?
Well, besides the trivial observation that modern elevators are run by software, this is an example of user interaction design. It recognizes human behavior and uses it to solve the problem. You might even call it a life hack.
So many software systems fight against human behavior. They put up punitive error messages to try to get the human to change their ways, or force the user through some complicated dance of gesticulations in order to get a simple task accomplished. But well-designed software recognizes the human as part of the system, and incorporates their behavior as-is into the solution.
Thursday, January 10th, 2008
Sometimes you have to act like you don't understand. My friend and former colleague from Radiant John Howison is a master of this technique. Having just seen Columbo: Agenda for Murder, I thought I would give it a try.
I just started a new engagement. My role on this project is not coder, not architect, but analyst. It is my job to document the requirements such that they are useful to the technical team. It is my job to ask questions.
Columbo was a fictional police detective who gathered information not by intimidation, and not by brilliant displays of intellect, but by acting like he didn't understand. He could always get people to give him information that they might otherwise withhold or ignore. Since that's my job on this engagement, I'm trying the same technique.
Admit that you are not the domain expert
In Agenda for Murder, Columbo put a secretary at ease by telling her that he didn't know how to use a fax machine or office telephone. Not only did he tell her, but his questions showed that he was no expert. He let her see that she had expertise that he himself didn't have. Once she was in that position, she slowed down and explained every detail of their operation. The key to solving the mystery might have been in those details.
Had he tried to show off his intellect and be superior to the secretary, she might have been less willing to talk to him. She might have just glossed over the details, since the Lieutenant must already know them. And so he might have missed some valuable information.
I've admitted to my client that he is the domain expert, not me. I've asked some stupid questions that proved that point. I didn't deliberately set out to ask stupid questions, but neither did I refrain from asking in case they were stupid. I'm not in an intelligence competition with my client, so I don't mind looking like I don't know something. It just encourages him to slow down and explain every detail.
Don't let an assumption go unchallenged
The premise of the show was that the murderer went to great pains to make the deed look like a suicide. Walking in on this scene, most people would make the assumption that it was, in fact, a suicide. That assumption would blind them to facts that say otherwise. People tend to bend facts to match their preconceived assumptions.
But Columbo did not allow this assumption to stand. As he walked into the crime scene, a fellow officer was relating the details that they discovered so far. In his tone and language, he indicated that it was a suicide. Columbo corrected him, taking away the veil of the assumption. With this new vision, he was able to spot quickly the evidence that indicated murder.
Walking into this engagement, I took stock of the assumptions I was making about the problem domain. Every fact that I use had to be backed up by a conversation of document that I exchanged with the client. If not, I document that assumption. Twice a day, I go through this list in person with the client. Usually my assumptions are correct, but we've already caught some rather large and dangerous misunderstandings this way.
But sometimes the assumption is the client's. It's difficult when talking to just one person to differentiate fact from assumption. Talking to more than one person and walking through scenarios verbally can help.
Ask the same question of multiple people
Columbo asked the suspect for details about the night of the murder. He then asked his alibi for the same details. There were, of course, slight discrepancies. These details may or may not have been important, but there was no way to know.
Columbo, of course, is trying to catch someone in a lie. I'm not expecting my clients to be deliberately withholding information from me, but each person has their own perspective on the project. Each person has their own goals, and their own experiences. These color the facts that they give me. By asking, I'm not looking for the answer, just their answer.
Walk through everything out loud
In the show, Columbo verbally walked through the suspect's description of events on the night of the murder. The suspect described how he received a phone call from the victim, how he sounded desperate, and how he declined to help. Columbo rewound the conversation and restated the "facts". He asked what was said that sounded so desperate. With this walkthrough, the suspect told him that the victim said "What am I going to do" twice and hung up. This is a detail that was not revealed in the first telling.
Later the suspect tells Columbo that he received a second call that night. Columbo reminds him that his wife only heard the phone ring once, so he claims that the call came in on call waiting. The fact that the victim hung up puts the lie to the suspects claims. But without walking through the scenario to extract details and establish timing, Columbo wouldn't have had this information.
I've verbally walked through the process with my client several times now. He provided use cases, which is a fantastic starting point, but they are no substitute for a live, personal, verbal walkthrough. Each time we go through it, I learn something new. Sometimes it's a detail in the use case that I missed. Other times, it's new information that I then add.
It's easier to act smart than to act dumb. Instead of posturing, I have to check my ego and realize that my client is smarter than me. And so far it seems to be effective. Although I have yet to produce any significant documentation, my client tells me I'm asking good questions.
Thursday, January 3rd, 2008
Why don't elevator panels have a really big button for the first floor?
Most people ride the elevator up to a particular floor, conduct their business, and then ride it back down to the first floor. Rarely does anyone need to ride between two upper floors. So by inference, half of the time you step into an elevator you have to push the "1" button.
Making the ground floor button more convenient will certainly make the others less so. But not all of the buttons are equal. The minor increase in effort spent looking for an upper floor button is far outweighed by the decrease in effort on the way back down.
When we design software, we usually think in terms of functionality. We want to cram in everything that the user might want, and account for every possible situation. Instead, we should focus on the things that the user does most often and make them the most convenient. It's not the feature matrix that sells software, it's the big red button that gets you where you want to go.
Wednesday, January 2nd, 2008
While giving a presentation at the Dallas .NET User's Group, I gave the audience something to snicker about. I run Vista on a MacBook Pro. So everyone had a good laugh at my expense when I couldn't get the projector working.
I had used a projector from my laptop before, so I was quite confused when the Windows Mobility Center insisted that there was no display connected. I kept hitting the "Connect display" button, it would say "Detecting..." and then switch back to "No display connected". I eventually borrowed someone's Dell laptop, after converting my Power Point 2007 presentation to 2003.
The information I found on line led me to update Boot Camp, and to replace the display driver from Apple with the one from NVidia. Though it apparently worked for some, it didn't make a difference for me.
Here's my solution
I eventually found that the external display worked if it was connected during power-up. If you plug in the projector before you boot, all is well. And if you are already booted up, just hibernate, plug in, and resume. If you get up to the podium and things aren't working, close the lid, wait for the front light to start snoring, then open it again.
Give this a try before your presentation and see if it works for you. And always keep your presentation on a USB thumb drive in the 2003 compatible format just in case.