Organization and Naming for LabVIEW Projects

This isn’t rocket science, but it can take a while to develop a good set of guidelines that work for you

In the last post, we discussed some of the bad organization smells that can result in poorly organized and highly coupled code. This article will show some best practices for organization and naming that will help mitigate some of these problems. It is not a substitute for learning more about good low coupling/high cohesion practices, but following these practices will force you to think about how you are organizing as you develop.

I am in no way advocating not taking the time to design your application on paper before coding, but I recognize the reality that many programmers jump in and start developing despite their best intentions to “do it right.” Following these practices will help mitigate the bad results of not doing a good design first and will let you get away without a good design on paper for longer before a solid design effort is needed.

Why is it important?

A good naming and organization scheme will help when it is time to decide where to put a file or how to name it. When you have a consistent approach, it will make your project structure easier to navigate and you won’t have to think as much about how to name it. Set up your own rules and follow them. If you come up with new ideas, sit on them until the next project so at least you are consistent within a project.

Below are the rules I use. Feel free to rip off my ideas, modify them, or devise your own. Every work environment is different and it may take some time to develop what works for your way of thinking.

This isn’t rocket science, but it can take a while to develop a good set of guidelines that work for you. A good naming scheme is not as trivial as it may seem. It is important to consider all your tools and how naming and organization fit with those tools. For instance, I use the NI GOOP Development Suite (GDS) icon creator. That tool works best with names that use underscores to separate important parts or namespaces. Because I find the GDS tool so helpful, I am fine with having it dictate part of my naming scheme.

What is a component?

I will use the term component frequently in this post, so a quick word about what I mean: a component is a group of highly cohesive methods and data that provide a clear interface to other components and is intended to be as decoupled from other components as possible.

A component interacts with a piece of hardware or a resource (file type, memory space, etc.) for use within a larger application, but the component does not need to “know” what that larger use case is (low coupling). Components are generally small, but they can sometimes grow very large. In that case, they should be evaluated closely to make sure that they are not violating their initial purpose by losing cohesion. Said another way, if a component starts to take on multiple personalities or purposes, then it should probably not exist as one component any more.

Here is an example of a clearly defined and cohesive component:

labview-cohesive-component-example

It is very clear what each of these methods do and what they interact with. In this case, the resource is an FTP server and the methods are pretty self-explanatory.

Here is another example with a larger component, but still very cohesive:

labview-another-cohesive-component-example

For most of what I am talking about below, a folder, a namespace, and a component are pretty much interchangeable.

Component folders

I talked in the last post about incorrect folder structure. So what is a better way to do it? In short, your folder structure should be relatively flat with each distinct component in its own folder. Here’s an example:

labview-component-folders-example

For larger projects, it may be necessary to group components into folders with similar components (drivers, file IO, etc.) to keep the structure manageable. Resist the urge to group components by application layer (client, real-time, etc.) as many times these components are used by multiple layers (like file IO). If you have code that is clearly specific to a particular layer or application within a larger system like a GUI manager for a specific client UI, then that would be a case for grouping components by layer.

Think of folders as a namespace for a particular component.

Folders are specific to your application, but I have a few that are very consistent as well as a plan for how to layout the project on disk.

Each of these folders should be flat unless you have a good reason to have a subfolder. I dislike the idea of the subVIs and controls folders. All those files are part of the component and it is a pain to move them around within that component’s folder when their scope changes, like when a VI changes from private to public.

If you need to make it more apparent which methods are part of the public API, use a library or class to mark private VIs as such. Don’t use the disk structure to hide VIs in an API. Moving or renaming files on disk, in SCC, and in LabVIEW simultaneously is painful. It shouldn’t be, but it is.

Here is an example of what an application folder structure looks like:

labview-application-structure-example

You may notice that a few folders are lowercase. I use this as an indicator that a folder is generic and contains the same kind of code across projects. Since this is not something I do except for very specific situations, “reuse” and “common” are the only two I use frequently.

File Naming

Now that I’ve talked about how to organize the application folders, let’s have a look at the anatomy of the file names themselves. Here is the format that I typically use:

Prefix_Component_Property/Method-Qualifier.extension

Project Prefix

There are some times I don’t use this, like in reuse code, otherwise, everything else should have a prefix. In the case of reuse code, it makes sense to use your company abbreviation as a prefix.

Pick an abbreviation of the project name: Digital Record and Playback (DRAP) or just use the full name if it is short.

Separators

  • Underscore (like_this) to separate namespaces/sections
  • S p a c e s within a section
  • Hyphen (like-this) to separate a qualifier

It’s not 1991 anymore. It’s time to embrace more than eight characters and spaces. Not saying you have to use spaces, but you can if you want to. It’s ok. Go ahead, try it. I’ll wait.

It didn’t BSoD your machine, did it?

Property/Method

A property is a datatype that is special to this component.

A method is a specific behavior (read, write, etc.).

Qualifier

A qualifier can be anything, but typically this is used to differentiate methods of a polymorphic VI (i.e. -U16, -U32, etc.).

SVN-specific considerations

Whatever naming you choose, begin the file name with at least three characters before the first space. This allows you to utilize TortoiseSVN’s autocomplete functionality in the Commit dialog.

LabVIEW-specific considerations

LabVIEW users have a few issues that force us to think about naming in a more unique way than other languages:

  • Dynamic dispatch naming
  • No two VIs can have the same name within any one namespace

The former means that some of our naming is already selected for us because a VI that overrides a parent class method must be named exactly the same as the parent class.

The latter means that you should avoid simple names that do not include some kind of namespace.

Ask yourself “does this fit?”

Whatever method you choose, files should be organized by use or task, usage, responsibility, interface, contract, etc.

When deciding where to place a file, ask yourself “what is this VI’s job?” not “what is this file’s type?”

Think of each folder as a library. Even if you don’t have those files grouped as a library, ask yourself “would it be appropriate to put these files together into a library?” If the answer is no, then you should rethink how files should be grouped. If you’re looking for help with your LabVIEW-based system, check out our capabilities and reach out if you want to chat.