Techniques for componentizing code
#61
Posted 20 April 2012 - 06:30 AM
Thankfully though, I've largely gotten over my irrational aversion to passing data via the messaging architecture. Contingent on the architecture being able to keep up with my data update rates!
#62
Posted 20 April 2012 - 07:13 AM
Sometimes for high throughput data streams I'll create a direct data pipe from the source to the destination to avoid loading down the messaging system. The pipe is just a native queue (or notifier depending on your needs) typed for the kind of data that is being sent. You can send the queue refnum to the data source and/or destination actors as a message. The data pipe is *only* for streaming data; all control messages (StartCapture, FlushToDisk, etc.) are still sent through the regular messaging system.Contingent on the architecture being able to keep up with my data update rates!
Certified LabVIEW Architect
Dak's First Law of Problem Solving: If the solution looks simple, I don't know enough about the problem.
Yes, the QSM is flexible. So is Jello. That doesn't make it good construction material.
There are two secrets to success:
Secret #1 - Never tell everything you know.
#63
Posted 20 April 2012 - 09:37 AM
I'm busily trying to create a logical construct, but its very much a learning process for me, I'm still struggling with the fundamental discussion of this thread, the problem of componentising code. I wish I could wrap my head around the whole "write a story where the nouns become objects and the actions become methods" but it just doesn't gel with me at the moment.
#64
Posted 20 April 2012 - 12:31 PM
Short answer: started (and had the first app using it) before I knew LapDog existed. Keep meaning to see if I can reformat the message part into a LapDog extension. Or make the messenger part interoperate with your "Message Queue”.Tell me again why you're developing all your own stuff instead of joining LapDog?
#65
Posted 01 September 2012 - 01:50 AM
#66
Posted 01 September 2012 - 03:37 AM
Name/Data messages (whether they are LVOOP or not) centralize the message handling code, are more familiar to most LV developers, support better natural decoupling, and (imo) require less work to refactor.
Theoretically command pattern messages are "safer." However, in practice I've found typos to be a non-issue. I write my message handlers so the default case handles any unexpected messages (such as from a typo) and generates an "Unhandled Message" notice for me. On rare occasions when I do make a mistake it is quickly discovered.
Neither is inherently better than the other. Name/data messages support my workflow and design requirements better. I'll use the command pattern only when I need it. Others swear by command pattern messages.
Certified LabVIEW Architect
Dak's First Law of Problem Solving: If the solution looks simple, I don't know enough about the problem.
Yes, the QSM is flexible. So is Jello. That doesn't make it good construction material.
There are two secrets to success:
Secret #1 - Never tell everything you know.
#67
Posted 01 September 2012 - 04:52 AM
I agree with everything Daklu has said (with the exception of efficiencyI'm curious if someone can speak to the benefits and drawbacks of having a case structure that takes a string from the message (as is shown in this example), versus something like the actor framework that has a Do.vi that is must override for every message. I feel the actor framework method of message handling is safer because the programmer is required to define a Do method for each message which defines how it is handled. In this example, the programmer still has the possibility of having a typo in his message name or case structure which would not be found until runtime. With the actor framework, it forces you to implement what to do when a specific message is gotten, and if this isnt' defined it is caught at compile time.
Pros:
- Much smaller code base.
- Single point of maintenance,
- Better genericism (what do I mean? Discuss
). - Looser coupling between messages and code (there is no code for messages).
- Less replication.(you don't need wizards or tools to save copying and pasting).
- Better portability (messages can easily be transmitted via ethernet, serial etc and interface to non-labview languages).
- Typos (trivial)
- State difficult to handle (e.g. timed/timeout responses).
Edited by ShaunR, 01 September 2012 - 04:58 AM.
Founder and general mischief maker on www.labview-tools.com.
SQlite aficionado and websocket zealot.
If it 'aint in LabVIEW, then you 'aint got a clue!
#68
Posted 01 September 2012 - 06:22 PM
Command pattern messages (Do.vi) are arguably a more OOPish design, they are more efficient at runtime, and yes, they eliminate the risk of typos in the case structure.
Name/Data messages (whether they are LVOOP or not) centralize the message handling code, are more familiar to most LV developers, support better natural decoupling, and (imo) require less work to refactor.
Theoretically command pattern messages are "safer." However, in practice I've found typos to be a non-issue. I write my message handlers so the default case handles any unexpected messages (such as from a typo) and generates an "Unhandled Message" notice for me. On rare occasions when I do make a mistake it is quickly discovered.
Neither is inherently better than the other. Name/data messages support my workflow and design requirements better. I'll use the command pattern only when I need it. Others swear by command pattern messages.
Thanks for the responses, guys. Hopefully this will never turn into the OOP version of the string vs. enum debate! I try to keep in mind this is LabVIEW, not c++ or JAVA so sometimes things will not conform perfectly to the generally accepted practices in those languages.
#69
Posted 03 September 2012 - 06:12 AM
Edited by for(imstuck), 03 September 2012 - 06:15 AM.
#70
Posted 03 September 2012 - 10:26 PM
Yeah, it probably would be safer. If you want to spend the time wrapping all the master messages in methods you certainly can--I won't tell you you're wrong for doing so.Would it be safer to have a "master" class as well which holds the queue ref in its private data and then pass that class to the slave loop instead? Then it would force messages sent to the master to have methods defined.
However, there are significant consequences of doing that. Having the slave loop call methods defined by the master loop makes the slave loop statically dependent on the master loop. Since the master already depends on the slave you now have a circular dependency in your design. That's usually bad. Managing dependencies is the single most important thing I need to do to keep my apps sustainable. Unfortunately it's rarely discussed. Probably because it's not as sexy as actors and design patterns.
I am curious why you're so interested in safety. Type safety is fine, but it costs development time to implement. Furthermore, the more safety you build into your app the more time it will take you to change the app when requirements change. Too much type safety will soon have you pulling your hair out every time your customer says, "I was thinking it would be cool if we could..."
I've never benchmarked examples. I got the runtime efficiency information from AQ and he's in a better position to know than I am.I agree with everything Daklu has said (with the exception of efficiency
)
Certified LabVIEW Architect
Dak's First Law of Problem Solving: If the solution looks simple, I don't know enough about the problem.
Yes, the QSM is flexible. So is Jello. That doesn't make it good construction material.
There are two secrets to success:
Secret #1 - Never tell everything you know.
#71
Posted 04 September 2012 - 12:53 AM
I am curious why you're so interested in safety. Type safety is fine, but it costs development time to implement. Furthermore, the more safety you build into your app the more time it will take you to change the app when requirements change. Too much type safety will soon have you pulling your hair out every time your customer says, "I was thinking it would be cool if we could..."
I'm not directly interested in only this, although I see why it came off that way. As I transition to using and fully understanding LVOOP, I just want to make sure I cover all of my bases, and there are certain points I understand more than others. So, some I may hammer home until I understand the best way, then move onto the next thing that I'll repeatedly ask questions about until I understand it fully
Edited by for(imstuck), 04 September 2012 - 12:53 AM.
#72
Posted 04 September 2012 - 03:58 AM
Fair enough. That's very similar to how I learned it too... start by learning the "academically correct" way to implement it, then once I understand that I can selectively implement only those aspects that are important for a given project.As I transition to using and fully understanding LVOOP, I just want to make sure I cover all of my bases...
Certified LabVIEW Architect
Dak's First Law of Problem Solving: If the solution looks simple, I don't know enough about the problem.
Yes, the QSM is flexible. So is Jello. That doesn't make it good construction material.
There are two secrets to success:
Secret #1 - Never tell everything you know.












