02-19-2015 04:14 PM
Hello. I have another one of my possibly misguided ideas. In my application, I need to open a communication channel between a slave device and a master device. To avoid passing lots of data around, I figured I would make both the slave class and master class attributes of the channel class, since a channel is always between one slave and one master. However, the slave can open a channel to more than one master (not sure if the converse is possible, but that's beside the point). Since LV is pass-by-value, I figured this might cause problems. Thus, when opening the second channel with the same slave, I think I want to add a reference to the slave object to the channel object, not a copy of the slave object. That way, if an attribute of the slave object is changed by accessing the slave attribute of the first channel, the slave attribute of the second channel will also reflect this change. So my question is: is this the way class references work in LV? Am I about to implement an anti-pattern? Someone please talk some sense into me...
Thanks,
-Jamie
02-19-2015 05:04 PM
After doing some research, it appears that Data Value References would behave in the manner I'm looking for. However, there are many caveats about DVRs to the effect of "if you want to use a DVR, you don't really understand data orientend programming" and the like. Before I do something stupid, it would be great to get some insight from a knowledgable member 🙂
02-19-2015 05:19 PM - edited 02-19-2015 05:20 PM
What you're describing is certainly possible and a even a good idea in cases like yours (although I'm not sure I'm tracking your description 100%). Could you provide a few references to the caveats discouraging the use of DVRs you mentioned?
There is a shipping example that might be of interest to you located here:
<LabVIEW Root Directory>\examples\Object-Oriented Programming\Reference Object
02-19-2015 05:23 PM - edited 02-19-2015 05:29 PM
I had to do something similar to this in one of my applications, and as you have mentioned I made use of DVRs to do so. I ended up with something like this (I believe it fits what the "gang of four" book would refer to as a decorator pattern). It could be used to pass any class "by reference".
So creating an instance of this class would look something like this:
The tTrigger class contains the hardware implementation. The tTriggerRef "decorates" it and its constructor looks something like this:
Each method on tTrigger Ref should simply read from the data value reference and make the appropriate iTrigger call:
If you have created a class like this, you may split the wire and each copy will only contain a data value reference back to the original class created by the initialization routine. The class is threadsafe in that only one thread can access the underlying data at a time.
Best Regards,
02-19-2015 08:07 PM
John,
Thanks for your reply. If I'm understanding you correctly, your class diagram looks something like this:
Is that correct?
02-19-2015 08:14 PM
Or perhaps this is a better representation.
02-19-2015 08:17 PM - edited 02-19-2015 08:17 PM
I guess I'm having trouble applying this to my situation... it appears that I don't need the decorator class. Am I missing the point?
02-19-2015 10:51 PM
02-20-2015 10:58 AM - edited 02-20-2015 11:05 AM
It's definitely not mandatory to use the decorator, you could just make the data inside the concrete class into DVRs and that class would behave how you want.
The decorator is a bit more flexible as it allows you to create the class as "by value" or "by reference" depending on the situation (though you might never need to use "by value"). Also it might end up being less work--in my case I actually had several concrete trigger types and implementing this with a decorator allowed me to change all of them at once into references without having to modify the existing classes at all.
EDIT: I actually looked at your class diagram--you could certainly have the reference simply contain an interface but not inherit from it. You wouldn't be able to use referneces and concrete classes interchangeably though (but maybe it's desirable to have a distinction between the two types in your case).
Best Regards,
02-20-2015 12:10 PM
Thanks John, I think I understand but I'll need to read your response a few more times to be sure. I don't typically understand the nuances of when to use which architecture paradigm until I come across a use case for it serendipitously. I'd like to get better at software architecture. I suppose that will happen with time.