How to Learn or Teach LabVIEW OOP

Last week was the European CLA summit and it was fantastic. If you are an architect in Europe and you didn’t go make sure to get your boss to budget it in for next year – I find it hugely valuable every year.

An interesting conversation I had a few times is about how to learn or train others on using LabVIEW Classes & OOP.

If you follow the NI training then you learn how to build a class on Thursday morning and by Friday afternoon you are introduced to design patterns.

Similarly when I speak to people they seem keen to quickly get people on to learning design patterns – certainly in the earlier days of adoption this topic always came up very early.

I think this is too fast. It adds additional complexity to learning OOP and personally I got very confused about where to begin.

To some extent I started again with my understanding following something like this process (in fact I still have to finish step 6) and I feel like it has made me a stronger developer. Thats why I share it here – it worked for me!

Step 1 – The Basics

Learn how to make a class and the practical elements like how the private scope works. Use them instead of whatever you used before for modules. e.g. action engines or libraries. Don’t worry about inheritance or design patterns at this stage, that will come.

Step 2 – Practice!

Work with the encapsulation you now have and refine your design skills to make objects that are highly cohesive and easy to read. Does each class do one job? Great you have learned the single responsibility principle, the first of the SOLID principles of OO design. Personally, I feel this is the most important one.

If your classes are large then make them smaller until they do just one job. Also pay attention to coupling. Try to design code that doesn’t couple too many classes together – this can be difficult at first but small, specific classes help.

Step 3 – Learn inheritance

Use dynamic dispatch methods to implement basic abstract classes when you need functionality that can be changed e.g. a simulated hardware class or support for two types of data logs. I’d look at the channeling pattern at this point too. Its a very simple pattern that uses inheritance and I have found helpful in a number of situations. But no peeking at the others!

Step 4 – Practice!

This stage is harder than the last. You need to make sure:

  • Each child class should exactly reflect the abstract methods. If your calling code ever cares which sub-class it is calling by using strange parameters or converting the type then you are violating LSP – the Liskov substitution principle – The L of solid.
  • Each child class should have something relevant to do in the abstract classes. If it has methods that make no sense this is a violation of the interface segregation principle.

Step 5 – Finish SOLID

Read about the open-closed principle and the dependency inversion principle and try it in a couple of sections of code.

Open-closed basically means that you leave interfaces (abstract classes in LabVIEW). Then you can change the behavior by creating a new child class (open for extension) without have to modify the original code (closed to modification). This goes well with the dependency inversion principle. This says that higher level classes should depend only on interfaces (again abstract classes). This means the lower level code implements these classes and so the high-level code can call the lower level code without a direct dependency.

This goes well with the dependency inversion principle. This says that higher level classes should depend only on interfaces (again abstract classes). This means the lower level code implements these classes and so the high-level code can call the lower level code without a direct dependency. This can help in places where coupling is difficult to design out.

I leave these principles to the end because I think they are the easiest to write difficult to read code. I’m still trying to find a balance with these – following them wholeheartedly creates lots of indirection which can affect readability. I also think we don’t get as much benefit in LabVIEW with these since we don’t tend to package code within projects in the same way as other languages. (this maybe a good topic for another post!)

Step 6 – Learn some design patterns

This was obviously part of the point of this article. When I came back to design patterns after understanding design better and the SOLID principles it allowed me to look at the patterns in a different way. I could relate them to the principles and I understood what problems they solved.

For example, the command pattern (where you effectively have a QMH which takes message classes) is a perfect example of a solution to meet the open-closed principle for an entire process. You can extend the message handler by adding support for new message types by creating new message classes instead of modifying the original code. This is how the actor framework works and has allowed the developers to create a framework where they have a reliable implementation of control of the actors but you can still add messages to define the functionality.

Once you understand why these design patterns exist you can then apply some critical thinking about why and when to use them. I personally dislike the command pattern in LabVIEW because I don’t think the additional overhead of a large number of message classes is worth the benefit of being able to add messages to a QMH without changing the original code.

I think this will help you to use them more effectively and are less likely to end up with a spaghetti of design patterns thrown together because that is what everyone was talking about.

Urmm… so what do I do?

So I know this doesn’t have the information you need to actually do this so much as set out a program. Actually, all the steps still follow the NI course on OOP so you could simply self-pace this for general learning material.

This doesn’t really cover SOLID very much from memory but if you google it you will find a HUGE number of resources on this, or you can get the book “Agile Software Development” by Robert Martin which I believe is the text that first coined the term SOLID (the principles already existed but this brought them together).

3 Comments

  • Fabiola De la Cueva

    March 16, 2017

    Love this post! I would only add that at the beginning, instead of creating a class from scratch, look at a small cluster type def that you are already using in your code. Preferably a cluster that represents something you can touch (such as a hardware device). Then, right click on the typedef on your project and select to convert it into a class. The code that is unbundling/bundling the cluster will break. You can start creating subVIs and move them inside the class. This exercise helped me understand how I was already using objects. From there, move into understanding SOLID and follow the outline suggested by James.

    I realized that we tell beginners to always convert their clusters and enumerators into typedefs. A new guideline would be: next time you create a cluster, decide if it should be a typedef or a class.

    Thanks,
    Fab

    Reply
  • Joerg Hampel

    March 17, 2017

    Thanks for the article, James. Typedef or class – that sounds very useful, Fab.

    Friday Fun Fact(?):
    Andrei told me just last week at the CLA summit that, while Uncle Bob grouped the five principles, he ordered them to spell out SOLDI in the first edition(s) of his book. Someone else pointed out that if ordered differently, they would form that cool acronym SOLID.

    Reply
  • Paul Morris

    March 19, 2017

    As part of a team just setting out down this road, that’s a useful lesson i think. Good post!

    Reply

Leave a Reply


By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close