LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

LVOOP question: "uses" vs "composition"

Hi guys,

 

Got a quick LVOOP question (not really sure where this should go). My understanding of LVOOP object "composition" is that one class has another class within its private data, and object "uses" another object is when one class has a method with a class as an input control. I've never used (ha!) "uses" before.

  • What are some rules of thumb for when to choose "uses" over composition?
  • What are some real-life examples where people have used "uses" before?

 

Thanks,

 

-wavepacket


------------------------------------------------------------------------------------

Please join the conversation to keep LabVIEW relevant for future engineers. Price hikes plus SaaS model has many current engineers seriously concerned...

Read the Conversation Here, LabVIEW-subscription-model-for-2022
0 Kudos
Message 1 of 11
(1,155 Views)

I think you're basically right. "Composition" (simply put) means you have a class in the private data of another class. Uses means it's an input, but doesn't stay in the private data.

 

Try to consider the question more broadly. Instead of a second class, consider a simple string value. Sometimes you need that string to be part of the private data of the class. Other times it's just an input to one of that class's methods.

 

Add the class to the child data if it needs to be part of the private data. Otherwise, just use it as a method input.

 

As for an example- an instrument driver usually needs some way to connect to the instrument. For example, some object that wraps a serial port communication method. You COULD wire the serial port object to every single method that needs to talk to the hardware device, but it's a lot simpler for the main device object to "have" a communication object that it reuses. You give it the communication object when you instantiate your hardware object, then it reuses the same one over and over again.

 

A "Uses" situation might be a specific test that gets run on the hardware, or a message that gets sent. The Actor Framework sends messages around. The actors don't have message objects, they use them. Messages don't get stored in the actor's private data (usually).

 

(Maybe I'm oversimplifying things.)

Message 2 of 11
(1,134 Views)

So its a little bit of a fuzzy determination then. When an object "uses" another object infrequently -> uses. When an object really is composed of another object -> composition.

 

Maybe an example with a car object. A car object certainly should be composed of an engine. However, it probably doesn't make sense to have a car object be composed of a trailer object just because some cars infrequently tow. In that sense, car object perhaps needs to have a method called tow which inputs a trailer object as a control?


------------------------------------------------------------------------------------

Please join the conversation to keep LabVIEW relevant for future engineers. Price hikes plus SaaS model has many current engineers seriously concerned...

Read the Conversation Here, LabVIEW-subscription-model-for-2022
0 Kudos
Message 3 of 11
(1,105 Views)

It can be frequency but it's really more of how it interacts with the main object. Again, think of a string control. Sometimes you want your main object to have a string as part of its private data, like an instrument name or an IP address. Other times you want to pass a string as an argument to something, like "print this" or "display this to the user". An object-based message popup may store the string input in its private data or it may not.

 

Maybe a better example would be a message logging object. The logger will likely store its file refnum internally to reuse, but would probably NOT store each individual message in its private data. It just uses the data once.

 

Expanding this to OOP, the message logger object might have an internal "LoggerDestination" abstract object with methods like Open, Write, and Close. Concrete classes of this might be "File" or "Popup window" or "Serial port". The logger itself will just call Write, and the LoggerDestination will override it with the relevant method. You COULD have LoggerDestination be an input for every time it calls Write, but since generally loggers have the same destination you can store that destination inside the class's private data.

 

The logger might be able to log different things, so let's describe an abstract "Loggable" object (or interface!) that has a "GetLogText" method in it. Concrete Loggables might be Error, String, or Event. The Error "GetLogText" method would return a string containing the error code and the call chain. The String "GetLogText" method might just return the string (for manual data entries). The Event "GetLogText" method might return an event source and a description.

 

Anyway, you'd then have your Logger object that has a Destination object. Logger's Write method would look like Logger.Write(Loggable). It uses a Loggable object once, then sends that string to Destination.

 

Frequency IS a good rule of thumb but it's more about how the main object uses the sub-object. Does it need to retain the sub object? If so, store it. Does it need to just act once on the sub object? Use it.

 

For your car analogy, I'd say Car would generally have an Engine in it. I'd say it might "use" a gas nozzle to refill it with gas.

 

I don't think you'd really say a car "uses" a trailer hitch but it does "have" a trailer hitch, so I'd probably inherit Trailer Hitch from Accessory and give the Car an Accessories array or something.

 

Or, you could use the Decorator pattern to expand the Car object.    

0 Kudos
Message 4 of 11
(1,089 Views)

^You're speaking of this: Decorator UML class diagram - Decorator pattern - Wikipedia

 

So in LV, a class would both inherit from its parent class but also contain a copy of its parent? Never seen this done in LV before...


------------------------------------------------------------------------------------

Please join the conversation to keep LabVIEW relevant for future engineers. Price hikes plus SaaS model has many current engineers seriously concerned...

Read the Conversation Here, LabVIEW-subscription-model-for-2022
0 Kudos
Message 5 of 11
(1,058 Views)

Yeah, that's basically it. Here's some discussion on using it in LV, including some of the limitations:

 

https://forums.ni.com/t5/LabVIEW-Development-Best/Decorator-Wrapper-Pattern/ta-p/3528153?profile.lan...

 

One of the common agreed upon points is that it's best for decorating existing, immutable code. If you can modify the code, giving it an array of "things it has" (accessories, in the car example, like a trailer hitch or an infant car seat or something).

 

I haven't used it myself because I don't run into immutable code very often. I generally can edit the main class to add an array to the private data.

0 Kudos
Message 6 of 11
(1,055 Views)

@WavePacket wrote:

^You're speaking of this: Decorator UML class diagram - Decorator pattern - Wikipedia

 

So in LV, a class would both inherit from its parent class but also contain a copy of its parent? Never seen this done in LV before...


Yes, this is for both the Decorator as also the Composite pattern. Don't confuse "Composite pattern" with object composition, not the same thing.

 

I do this, it's very powerful.

0 Kudos
Message 7 of 11
(1,052 Views)

Composite pattern is a new one to me too...what code usecase/problem does composite pattern solve?


------------------------------------------------------------------------------------

Please join the conversation to keep LabVIEW relevant for future engineers. Price hikes plus SaaS model has many current engineers seriously concerned...

Read the Conversation Here, LabVIEW-subscription-model-for-2022
0 Kudos
Message 8 of 11
(1,045 Views)

@Intaris wrote:

@WavePacket wrote:

^You're speaking of this: Decorator UML class diagram - Decorator pattern - Wikipedia

 

So in LV, a class would both inherit from its parent class but also contain a copy of its parent? Never seen this done in LV before...


Yes, this is for both the Decorator as also the Composite pattern. Don't confuse "Composite pattern" with object composition, not the same thing.

 

I do this, it's very powerful.


Is this what you are speaking of? https://refactoring.guru/design-patterns/composite


------------------------------------------------------------------------------------

Please join the conversation to keep LabVIEW relevant for future engineers. Price hikes plus SaaS model has many current engineers seriously concerned...

Read the Conversation Here, LabVIEW-subscription-model-for-2022
0 Kudos
Message 9 of 11
(909 Views)

I have it from the GoF book, "Design Patterns". Outdated in a way, but some of the ideas still hold.

 

Composition is grouping together of objects in a single object. The objects are not interchangeable and don't have any specific relation to each other.

 

Composite on the other hand allows Composition, but with the added point of shared parents and the ability to treat a composite object the same way as an individual object (leaf). So yew, it's the same as your linked content.

0 Kudos
Message 10 of 11
(899 Views)