Tuesday, March 8, 2005

When UIs and Workflows Go Terribly Wrong

I heard about this story on NPR today and followed up on the source's web site, which is the Journal of the American Medical Association. To summarize very briefly, many hospitals now use a system called the "Computerized Physician Order Entry System" (CPOE) for patient prescription input. After a study they found the system's workflows and UI were so poorly designed that at best they're inefficient, and at worst they can cause serious problems. In one of the interviews on NPR today the gentleman being interviewed said that if, for example, you wanted to take a patient from an 8-per-day dosage of something down to 4-per-day, you had to enter the new dosage first, and then cancel the old dosage. If you just enter the new dosage and something happens or you get pulled away, then suddenly that patient's getting a 12-per-day dosage. Yikes!


I just thought it was interesting because while we all of course strive to build systems that are user-friendly on the front-end and robust on the backend, in cases like this a poorly designed system can cause serious problems. Even though the systems many of us develop might not be this mission-critical, it's a good case study in what not to do when we build applications.

Monday, March 7, 2005

How Much Should Objects Know About Themselves?

This question came up in our CFUG meeting last month when I gave a CFC-101 presentation, but I was reminded of it again today while reading this article about Service-Oriented Architecture. Here's the pertinent quote that caught my attention:


"The idea of SOA departs significantly from that of object oriented programming, which strongly suggests that you should bind data and its processing together. So, in object oriented programming style, every CD would come with its own player and they are not supposed to be separated. This sounds odd, but it's the way we have built many software systems."


In the context of the discussions we had at our CFUG meeting, this specifically came up when I was discussing the bean objects in the sample application I built. Several people thought they seemed too simple, and that I was leaving a bunch of methods out of the beans for the purposes of illustration. The beans actually were relatively "real-world" examples albeit limited in the number of attributes they contained. Some people were wondering where the view() or display() methods were, and how the data in the beans would actually get displayed, which is a rather fundamental error in logic (IMO anyway) with respect to how much objects should really know about themselves.


 


This debate actually ties in directly with the quote from the SOA article. While on the surface the quote may seem correct, there is something a bit off about it to me. In OOP we of course say that an object's methods and its data are both contained within the object; this is a hallmark of OOP and one of the features that most distinguishes OOP from procedural programming. What isn't so cut-and-dry, however, is exactly *which* methods should be contained within the object. Where does it make sense to start taking methods out of the object and create another object to act as a service layer?


Using the example from the article, should a CD object know how to play itself? Some would say yes, citing the self-contained mantra of OOP. I, on the other hand, would likely say no, a CD shouldn't know how to play itself, any more than I would say a Person bean should know how to display itself.


Why would I say that? Because to me if you take the notion of self-contained objects too far, you're breaking two of the other tenets of OOP, namely tight cohesion and loose coupling. If a CD knows how to play itself, that may be taking things one step too far because while all CD objects get played the same way, what if you want to feed your CD object to a different type of player in the future? Now obviously in other cases you *do* want to have polymorphic methods to handle things like this, so in the classic Shape object example, you might have a draw() method that gets implemented differently for a circle than it does for a square.


Let's think about the CD again for a minute. Should a CD, LP, and cassette object each inherit from a single parent and have polymorphic play() methods? Or would it be better to have the media objects be just a bit more ignorant of themselves and have a service-type object, such as a Player, handle the play() method based on the media given to it?


As with so much in OOP, the answer is "it depends." In the case of something like a Person bean, if you have a display() method within the bean itself you're severely limiting its usefulness and the overall flexibility of the bean. Better to have a slightly more dumbed-down bean that can be used by multiple front-ends through a service architecture of sorts.


At any rate, this thought came back to me while reading this article, and it's something we have to be mindful of as we build object-oriented systems. There are no hard-and-fast rules but certain ways of doing things make more sense than others, and we should always be mindful of making our objects as reusable as possible. If you want to display a Person in more than one way, or you want to play a CD on more than one type of player (e.g. standard player vs. computer drive), then consider dumbing down your objects a bit and creating a service object to handle things. This can make for a far more flexible system than can more easily be expanded in the future.


Comments


I don't think a CD should know how to play itself. I want to be able to transfer it from my home stereo to my car. I want be able to rip it into MP3s. But the purpose of a metaphor, as Martin Fowler says, is not to give you the answers, but to help you figure out what questions to ask. A CD can be heard through headphones or a car stereo. Can your bean be viewed different ways? Can its data be extracted and reencoded in a new format?


Thanks Patrick. The way I think of beans is no different than what you're saying about CDs. The beans hold the information, but what's done with it is not prescribed by the bean itself. So long as the bean provides methods to get at the data it contains, it doesn't know or care what's using it and how it's getting displayed, which in my mind is the best way to keep it flexible. If the bean is generic I can drop it into an HTML front-end, a Flash front-end, or even drop it into a Flex application without any changes to the bean itself.


That SOA quote is absurd and terribly misleading! Even in the purist OO world, we should recognize that a CD player exists and has many variants. Our "real-world" model should lead us to somehow inserting a CD object into a CD player object with the knowledge that a CD does *not* know how to play itself - that's the job of the CD *player*. It's exactly this sort of nonsense that can get OO a bad name because it's used as (bad) justification of why OO doesn't "work"...


Thanks Sean, that's why I posted the quote--seemed to me to be at best a misunderstanding or at worst a misapplication of OO principles as a means of attempting to illustrate an absurdity of OO that doesn't exist. If there actually is a system designed as the SOA quote outlines I'd argue it's not a *well*-designed system and certainly shouldn't be taken as an example of OOP.

Saturday, March 5, 2005

Loving CFMX 7 Forms

After working heavily with the new forms capabilities in CFMX 7 for the past week or so, I want to personally thank the ColdFusion product engineers for the hard work in this area. This is by far the biggest productivity gain to ColdFusion in quite a while, and when a huge productivity gain like this is added to a tool that already beats the pants of its competitors for productivity, then the competitors better look out!


Since most of what I've been working on lately involves file uploads I've been focusing on the XML forms (XForms) and this is seriously cool stuff. I can finally just worry about the form elements themselves and not spend all my time doing formatting of the display. Not having to create HTML tables for the layout of my forms is a huge time saver, and the flexibility of being able to apply a different skin to my forms makes them extremely reusable. I can definitely see grabbing forms from one app and sticking them into another and just applying a new skin, whereas before it was often more of a pain than it was worth to reuse forms because of all the changes that would be necessary.


Bottom line: CFMX 7 completely rocks for working with forms. Flash Forms are cool as well, but even if you aren't a fan of those, you seriously need to check out XForms. Power, flexibility, and separation of the form elements from their presentation makes for a happy developer!


Comments


Agreed, i loathe FLASH Forms.. but damn well near worship the XML Forms + XLST!


I haven't looked into these much yet, but can you do file upload with Flash Forms, and if so, are there any File Upload Progress bars for the form? That has been a huge complaint in the past... having no idea how long an upload will take?


Nope, currently you can't do file uploads with Flash Forms. This is a limitation of the Flash player itself--it doesn't allow for file uploads. It's a frequently-requested feature to be added to the Flash player though, so I bet we'll see this eventually.


Are the XForms compatible with all browsers? Last time I read about them (a while ago) they weren't.


Yes, the XForms that CF generates are compatible with all browsers (no plugin needed) because CF generates standard HTML/CSS stuff on the server side before it's delivered to the user.


I don't think we will see file upload capability in the flash player any time soon. It potentially creates a HUGE security issue. You can do file uploads from flash with a little bit of javascript and the willingness to use a pop-up window. It's not the most elegent solution, but it gets the job done.


Not sure why it creates more of a security issue than any other file upload ... if it worked the same as a regular HTML file upload I don't see what the issue would be. If nothing else it could prompt the user like when a Flash movie tries to access your camera or microphone. I also don't think it'll be that long until it's in there. File upload capabilities are already built into Central so I wouldn't be surprised if it gets into the next version of the Flash player.


Ahh, after looking into it, I was getting XForms confused with the W3C's XForms (http://www.w3.org/MarkUp/Forms/2003/xforms-for-html-authors.html). Theirs is the one not compatible with many browsers currently. Once it's supported, it will really change the way forms are created.


Chris--CFMX 7 generates XForms-compliant XML when you use cfform format="xml". You can then apply a "skin" to this XForms-compliant XML, and that's what transforms the XML into HTML. You can grab the XML that CF generates and use it as straight XForms code, however, so the CF forms *do* comply with the W3C XForms standard.


Matt, thanks for the clarification. I just tested it out, and works as you said. Pretty cool!


I'd love to see real life code examples of your XForms.


I have an article that should be up on Fusion Authority before long that gives a simple example. When I finish up our CFUG web site I'll be sharing the code for that whole application and it has quite a few XForms in it.


For anyone else that comes across this entry looking for good examples, Here is the article that Matt mentioned in the comment above.