Tuesday, January 09, 2007

Designing VIs Before You Write Them

One of my readers requested I talk about the design process for the object-oriented Getting Started window.

I'm not suggesting this is a perfect, general design process for OO in LabVIEW, but perhaps some people will find an example helpful.

First, I identified the "nouns" in my system: the links. The Getting Started window uses a web-style UI, and the most important things are the hotspots that take actions.

The links became the objects in my design. Link became my common ancestor class.

Next, I wrote down (on paper - yes, this was all done before I started writing any code) the "verbs" for my objects. They had two primary actions: initializing their data from an XML file and taking action when the user clicked on them. These became the methods on my class.

Next, I thought about the "kinds" of links I had: some opened web pages, some created VIs, some launched wizards, etc. These became classes that inherited from Link.

For each of these child classes, I wrote down all the information they needed in order to perform their work. For example, the Web link needed to know the URL to open. These became the fields of the class private data.

If there was a field that all the child classes had in common, I thought about whether it was an attribute of all links and (if so) put it in the parent class.

Then I hit a small snag: the Targets ring that appears when you have modules such as Real-time installed.

When looking at the information that the ring items needed, I decided to create a new layer in my class hierarchy. I made Clickable text, a child of Link, and made another child of link called Ring item. Then I redistributed the private data fields accordingly.

This was all pretty straightforward. But then I hit a bigger snag: while designing the child classes of Ring item, I realized one launched a project wizard. But it was also possible to have a clickable text link that launched a project wizard.

"Where should I put the fields for a project wizard?" I asked myself.


I could duplicate the exact same fields in the Project wizard clickable text class and the Project wizard ring item class. But that's not good. Duplication is almost always a bad sign: that means when you make a change in one place, you have to remember to change the other place as well. Sharing code between the two is better.

I considered putting the fields in the common ancestor class, Link. But that's not good, either. That would mean that all the other child classes would contain fields that were useless to them. That's inefficient, and also confusing to other engineers who want to modify my VIs later.

Ordinarily with OO design, you want to put common functionality into a common ancestor class. But the class hierarchy I wanted to use didn't allow that in this case. There was no common ancestor unique to the project wizard classes.

Then I realized the design pattern I wanted: delegation. I created another class (which did not inherit from Link) which launched a project wizard. Then, rather than have the private data fields in the original two classes, I gave them each a private data member that was an instance of the helper class.


After reviewing my design with another engineer, I was confident I had a good approach and started writing VIs.

Up-front design work isn't a guarantee that you won't need to change your design later (when you get new requirements or think of a better approach), but it does reduce the likelihood. When people don't take the time to design before coding, too often they will want to "stick with what they already wrote" instead of using the design they like better.

Of course, I think this applies to software in general, and not just object-oriented design. "An ounce of prevention is worth a pound of cure." :-)

Labels:

2 Comments:

Blogger Aart-Jan said...

Hi Christina, I have a "what if" question for you:
What if every item in the ring control were in itself well represented by a link class, would it have been possible to implement the ring control as an array or collection of link instances?
I don't have much experience in OO programming, but even when designing code in Labview I wonder how I can make some kind of representation of a collection of objects.
Thanks,
Aart-Jan

11:58 AM, January 14, 2007  
Blogger Christina said...

Aart-Jan,

I'm not sure I understand your question correctly. The items in the rings have managing objects, the same way the hyperlink-style items do. The classes for the ring items inherit from the Link class.

I use an array to store the managing objects of the ring control.

Can you help me understand your question better?

Thanks,
Christina

5:03 PM, January 25, 2007  

Post a Comment

<< Home