BreakPoint

cancel
Showing results for 
Search instead for 
Did you mean: 

LV OOP small tutorials and introductions in a "workshop style"

If others reply contradicting me, believe them.

 

I think it is called the "Compensation" pattern where a class contains another class. Think cluster in a cluster. By using classes instead of clusters we can over-ride what would have been one type of cluster (think VISA serial port reference in the first cluster) by creating child class of the "internal cluster" with a child class that has a TCP connection.

 

Now I have seen code written such that the data is not in the class but in a class in the private data but that was damn hard to follow. It was as if the original developer wanted to write the last State Machine  and thought that the states would be data of a class for each type of state machines and wanted to completely decouple the Class that was the State Machine from any data used in the State Machine.

 

Maybe the good doctor can explain that design pattern but not me. While modifying that code I found myself channeling Ren of Ren and Stimpy when he said "What were you thinking man?"

 

Not OOP trained and not pretending to be one.

 

Ben

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
Message 21 of 31
(5,251 Views)

Ben wrote:

I think it is called the "Compensation" pattern where a class contains another class.


The term is actually​ "composition".  In the OO world, it defines a "has a" relationship.  For instance, you can have a class for an engine and a class for a car.  The car class will have an engine class in its data (a car has an engine).

 

In this case, the VISA resource can already give you the TCP, serial, and GPIB capability for free.  So I don't see much point in composition.

But you could make a child class to handle the RS-485.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 22 of 31
(5,243 Views)

For those who are serious about learning Object Oriented Programming in general, I very highly recommend The Object-Oriented Thought Process.  It just may open up a new world for you in how you program.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 23 of 31
(5,225 Views)

@crossrulz wrote:

Ben wrote:

I think it is called the "Compensation" pattern where a class contains another class.


The term is actually​ "composition".  In the OO world, it defines a "has a" relationship.  For instance, you can have a class for an engine and a class for a car.  The car class will have an engine class in its data (a car has an engine).

 

In this case, the VISA resource can already give you the TCP, serial, and GPIB capability for free.  So I don't see much point in composition.

But you could make a child class to handle the RS-485.


Right and right!

 

As usual thank for reading what I meant and not what I wrote.

 

Ben

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
0 Kudos
Message 24 of 31
(5,214 Views)

@Blokk wrote:

Thanks for the good hints! Or, if I just wanna keep the things in one place and easily expandable to N+1, I could just use arrays (but of course I need to be careful to keep track of the array element orders!):

 

class_array.png


In stead of making an array of classes, you can make a composite class that holds the array. At first this seems like a lot of work, but it's usually worth the effort. You'll need to override each method, and in a for loop execute the method itself (not call parent, you're not calling the parent). The methods don't need to be re-entrant, unless you plan on doing recursive containment (composite has nodes, node can be composite, also lot's of fun), or parallel execution of the same class methods.

 

Imagine you have an entire program using only one program. Giving the parent a composite child containing an array of parents, would automatically enable your entire application to work with N classes instead of 1. This works great for filters, file writers, visualisation classes, etc. If you enable parallel execution on each for loop, the classes will be executed in parallel, basically obsoleting 50% of the use cases of call and collect.

 

A slight variation would be if the composite class doesn't act on all classes in the array, but only one that's selected. The child can have additional methods, extending the parent. Methods like Select, Add, Delete, can add dynamic properties to what used to be a humble class.

 

And an thing that can't be emphasised enough is that as long as the contract is honoured, your entire application will work. That's not just theory, it's often like that in practice.

 

In my experience, a picture is worth a 1000 words:

Composite.png

Message 25 of 31
(5,177 Views)

I am not sure I understood everything, lots of new concepts and things to digest! 🙂 I will try to read more and more and see some examples. Maybe you know some code example (link, etc) where a simple example of "composite class" is shown with the above explained use case?

 

edit: actually I do not need to program large applications and I have to deliver medium sized ones like 1-2 per year. I also program alone. I see this as the main limitation at my recent work place which blocks me to dive deep into OOP. Practically I do NOT need OOP here that is the main point 🙂 But it does not mean I do not want to be a better LabVIEW programmer...(even if I am a physicist by qualification and position)

 

edit2: another part of the motivation to learn more, that I leave my work place in 2018, earliest in July, latest in December (end of contract). It might happen that I end up as a LV programmer instead of a researcher??? Smiley Surprised

Smiley Very Happy

0 Kudos
Message 26 of 31
(5,183 Views)

@Blokk wrote:

I am not sure I understood everything, lots of new concepts and things to digest! 🙂


Not that much new concepts, just for loops in VI's ;).

 

With OO, you'll find you'll need to invest some time to grasp a few concepts. Once you do, they'll go a long way (all the way in fact).

 

Composites are not that hard, but this particular situation might not be the easiest to start with. The idea of putting an array of parents in a child is a bit "funky" at first. At first I tried an array of childs in the parent, that won't work (for good reasons). I'd advice to get familiar for normal composition first. The Serial\TCPIP composition is mostly (e.g. the init's could be different, one taking serial settings, the other IP address and port) redundant from a technical point of view. From a tutorial point of view it's a good example. Your drivers using an interface, that's basic composition.

 


@Blokk wrote:

I will try to read more and more and see some examples. Maybe you know some code example (link, etc) where a simple example of "composite class" is shown with the above explained use case?


The NI OO class is actually a very decent start. Not as much in there as I'd like to see. NI courses usually cover only the semantics. The context is often missing. So you'll get a good picture of what you can do, not what you should do.

 

I did a presentation on NI Days about how to get started. I'll do it on NI Week if they let me. A revamp would include new examples. Not in the presentation, but as bonus material.

 

Good OO code examples are rare. The shipped graphics example is an example of composition. Never did much for me though. The problem is the result isn't really what is interesting. The way to get there and the consequences are what it's all about. You loose that with a code example.

 

Starting with OO is 70% of learning OO. With your experience I'd assume you'll be up and running in no time. It took me 10 years to get started, 2 weeks to get to like it, and maybe 1-2 year to get really comfortable with it.

0 Kudos
Message 27 of 31
(5,175 Views)

Blokk wrote:

edit: actually I do not need to program large applications and I have to deliver medium sized ones like 1-2 per year. I also program alone. I see this as the main limitation at my recent work place which blocks me to dive deep into OOP. Practically I do NOT need OOP here that is the main point 🙂 But it does not mean I do not want to be a better LabVIEW programmer...(even if I am a physicist by qualification and position)


I'm a physicist by education, but only worked as a software developer.

 

Yes, it's hard to see the point without some typical problems that scream OO. I'm still trying to get everyone at our company to switch, but they don't get these problems (only 5-20 small project, where I have 1X4 years project + noise). Once to take the leap, you don't want to go back, but it takes a push to get it started.

 


Blokk wrote

edit2: another part of the motivation to learn more, that I leave my work place in 2018, earliest in July, latest in December (end of contract). It might happen that I end up as a LV programmer instead of a researcher???


I'm sure you put yourself in the pictureSmiley Happy. For us, non residents are just to difficult to hire! The LabVIEW Developers Seeking Employment forum isn't very active, but people might get notifications on that forum (I do).

0 Kudos
Message 28 of 31
(5,172 Views)

For me, the 100% best time to use classes is for hardware interfacing libraries/wrappers. The reason for this is that I can easily swap out one instrument for another without having to change the code (or at least, not very much) that deals with the instrument (e.g. my DAQ loop). Where I most see the benefit for this is being able to have simulated instruments.

 

I work remotely a lot and often don't have the instrument to hand which means if I ran my code with the instrument drivers I would get errors everywhere and wouldn't be able to easily test the rest of my application.

 

Without OOP, I would probably have to have a bunch of conditional/case structures to disable the instruments. With OOP, I can initialise a SimulatedDevice.lvclass instead of a RealDevice.lvclass which generates simulated data (e.g. when running in the development environment).

 

Here's a screenshot of a project I'm currently working on:

2017-12-12_10-59-50.png

 

In my DAQ Main.vi, I call the parent methods from DAQ.ctl for initialising, closing, acquiring data and setting the channel on/off state. I then have a simulated DAQ which just returns random data (with a channel-based offset) and my real DAQ. In this particular project, the channel on/off isn't used but I've used this same hierarchy in 3 projects now and each time I've used it I've used the same DAQ loop, the same simulated DAQ instrument and then just 'filled in the blanks' for the real DAQ.

 

All of the references used are contained within the class and stored in a nice class wire. Apart from initialising some class specific properties (in a case structure), everything else is nicely hidden away encapsulated.

 

Also, my advice would be to find some small examples like this where OOP fits and really makes sense to you - this will help you to learn the concepts and good OOP programming practice. You can then start to look at more complicated frameworks/architectures using OOP. The next logical step for me was to learn how to do by-reference classes (where you can split the class wire but it's still a single instance of the class).


LabVIEW Champion, CLA, CLED, CTD
(blog)
Message 29 of 31
(5,088 Views)

Sam's post above reminded me of another point that I should share.

 

I believe there is a limit to how much of an application in LV SHOULD be LVOOP. Just because we could is not a good reason. So where would I draw the line between LVOOP and non-LVOOP? At the very least, when you get to the top level application VI itself. But if you are developing the same type of application doing the same or similar all of the time then maybe go all of the way. But in my case I develop so many unique applications that as I approach the top of the hierarchy and encounter code that is very specific to just one application, I find it more efficient to just go with normal LV.

 

Moral of the story

 

You do not have to go all LVOOP, just start somewhere.

 

Ben

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
Message 30 of 31
(5,072 Views)