取消
显示结果 
搜索替代 
您的意思是: 

Using a class reference as an attribute of another class...

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

0 项奖励
1 条消息(共 11 条)
6,555 次查看

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 🙂

0 项奖励
2 条消息(共 11 条)
6,543 次查看

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

Tom L.
0 项奖励
3 条消息(共 11 条)
6,534 次查看

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".

 

  1. An abstract interface class (iTrigger in my example) defines the methods required.
  2. A concrete class (tTrigger in my example) inherits from the interface class.
  3. An extra "decorator" class (tTriggerRef in my example) inherits from the abstract interface and also contains a data value reference to an abstract interface.

 

So creating an instance of this class would look something like this:

 

tTriggerRef.png

 

The tTrigger class contains the hardware implementation.  The tTriggerRef "decorates" it and its constructor looks something like this:

 

tTriggerRef.lvclassInit.png

 

 

Each method on tTrigger Ref should simply read from the data value reference and make the appropriate iTrigger call:

 

tTriggerRef.lvclassStart.png

 

 

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,

John Passiak
0 项奖励
4 条消息(共 11 条)
6,530 次查看

John,

 

Thanks for your reply.  If I'm understanding you correctly, your class diagram looks something like this:

 

Untitled.png

Is that correct?

0 项奖励
5 条消息(共 11 条)
6,502 次查看

Or perhaps this is a better representation.Untitled2.png

0 项奖励
6 条消息(共 11 条)
6,497 次查看

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?

Untitled3.png

 

0 项奖励
7 条消息(共 11 条)
6,494 次查看
DVRs are just fine. I use them in conjunction with OO all the time. Using them together can give you some really neat capabilities. On my website you can find the text of a paper i delivered on OOP at NIWeek last year -- the link in in my signatures.. Don't worry about what the dope told you, he was probably a C++ programmer...

Mike...

Certified Professional Instructor
Certified LabVIEW Architect
LabVIEW Champion

"... after all, He's not a tame lion..."

For help with grief and grieving.
0 项奖励
8 条消息(共 11 条)
6,478 次查看

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,

John Passiak
0 项奖励
9 条消息(共 11 条)
6,438 次查看

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.

0 项奖励
10 条消息(共 11 条)
6,427 次查看