Jump to content

Need help with OO design


Recommended Posts

I've been trying to dig into LVOOP but I've run into some issues. This is my first attempt at OO design and implementation so I'm thinking I would get some advice before I pull all my hair out.

My objective is to build an application that could acquire data from multiple source. This application will have a means to configure each data source and load/save configurations to file.

My first crack at this from an OO approach:

1- Create class called "unit". This represents a data source. Class data is "name" and "description"

2- Create class called "serial unit". This inherits from "unit" but also has additional class data such as visa refnum, com functions. This class also has an array of "Channels" objects

3- Create class called "Channels". Contains channels information such as name, location, units, scaling etc.

4- Create class called "Configuration". This class contains an array of "unit" objects along with config path.

In my app, I start by creating a "Configuration" object. The user can then add a "unit" to the configuration. Now the GUI to add a unit will change depending on the type of unit they would like to add. So if a user chooses to add "serial unit", I need to somehow convert my "unit" object (element in configuration) into a "serial unit" object (so that I can access "serial unit" specific methods). I've tried using "to more specific class" but it gives me an error Error 1448: Bad type cast. LabVIEW cannot treat the run-time value of this LabVIEW class as an instance of the given LabVIEW class."

My next crack would be to change my configuration class to contain and array of serial units, array of daq units, etc.. for all my unit classes, rather than an array of "units". Is this the correct approach?

Link to comment

I've been trying to dig into LVOOP but I've run into some issues. This is my first attempt at OO design and implementation so I'm thinking I would get some advice before I pull all my hair out.

My objective is to build an application that could acquire data from multiple source. This application will have a means to configure each data source and load/save configurations to file.

My first crack at this from an OO approach:

1- Create class called "unit". This represents a data source. Class data is "name" and "description"

2- Create class called "serial unit". This inherits from "unit" but also has additional class data such as visa refnum, com functions. This class also has an array of "Channels" objects

3- Create class called "Channels". Contains channels information such as name, location, units, scaling etc.

4- Create class called "Configuration". This class contains an array of "unit" objects along with config path.

In my app, I start by creating a "Configuration" object. The user can then add a "unit" to the configuration. Now the GUI to add a unit will change depending on the type of unit they would like to add. So if a user chooses to add "serial unit", I need to somehow convert my "unit" object (element in configuration) into a "serial unit" object (so that I can access "serial unit" specific methods). I've tried using "to more specific class" but it gives me an error Error 1448: Bad type cast. LabVIEW cannot treat the run-time value of this LabVIEW class as an instance of the given LabVIEW class."

My next crack would be to change my configuration class to contain and array of serial units, array of daq units, etc.. for all my unit classes, rather than an array of "units". Is this the correct approach?

I think that is the factory design pattern.

http://zone.ni.com/wv/app/doc/p/id/wv-1295

You build an array of all of the children of "unit" and populate a ring (for example) with each option. WHen the user selects using the ring, you can then index the array of classes to chose the flavor the user selected.

To configure each you can call config method for the selected path that invokes the appropriate over-ride VI to show a FP and let them configure it.

I'm not sure if any of tht helped,

Ben

Link to comment

I think that is the factory design pattern.

http://zone.ni.com/wv/app/doc/p/id/wv-1295

You build an array of all of the children of "unit" and populate a ring (for example) with each option. WHen the user selects using the ring, you can then index the array of classes to chose the flavor the user selected.

To configure each you can call config method for the selected path that invokes the appropriate over-ride VI to show a FP and let them configure it.

I'm not sure if any of tht helped,

Ben

Thanks for the reply.

I took a look at that presentation but I'm not sure it solves my problem.

It looks like the factory pattern has a vi which determines which sub-class to create an object from. So in my case I can select "serial unit" and I can get a "serial unit" object out. The problem is when they want to edit the "serial unit" object. Since I currently store all my units as "unit" objects (config class), when I try to get a unit that I know is a "serial unit", I get the error mentioned above. I think I'm coming to understand why this does not work. Say I create a new "serial unit" and add this to my configuration object as a "unit". At this point I think I have lost all my "serial unit" specific data, so when I try to go back to access my "serial unit" LabVIEW complains because the "unit" object no longer has my "serial unit" specific attributes.

Is there a better way of doing what I'm trying to do?

Link to comment

Thanks for the reply.

I took a look at that presentation but I'm not sure it solves my problem.

It looks like the factory pattern has a vi which determines which sub-class to create an object from. So in my case I can select "serial unit" and I can get a "serial unit" object out. The problem is when they want to edit the "serial unit" object. Since I currently store all my units as "unit" objects (config class), when I try to get a unit that I know is a "serial unit", I get the error mentioned above. I think I'm coming to understand why this does not work. Say I create a new "serial unit" and add this to my configuration object as a "unit". At this point I think I have lost all my "serial unit" specific data, so when I try to go back to access my "serial unit" LabVIEW complains because the "unit" object no longer has my "serial unit" specific attributes.

Is there a better way of doing what I'm trying to do?

What you're doing should work. There's no reason your classes should be losing their association with their specific type if everything is coded properly - your serial unit should always "know" that it's a serial unit even if it's passed to a VI that expects a generic unit. You might need "Preserve Run-Time Class" on an output of a VI somewhere.

Link to comment

What you're doing should work. There's no reason your classes should be losing their association with their specific type if everything is coded properly - your serial unit should always "know" that it's a serial unit even if it's passed to a VI that expects a generic unit. You might need "Preserve Run-Time Class" on an output of a VI somewhere.

The problem is that my "Add/Edit Unit" GUI is different for each Unit. I have coded an "Add/Edit Serial" GUI that expects a "serial unit" input. If I try to cast my "unit" object into a "serial unit" before passing it into the vi, I get the error mentioned above. If I pass a "unit" object into it, it does not compile. If I make the input terminal a "Unit" object type, I cannot access my "serial unit" specific information.

I suppose I could make "Add/Edit Unit GUI" as a method for "Unit" class, and this will get over written for each child class of "Unit" ("serial unit"). Then I can pass in a "Unit" object into the "Unit.Add/Edit GUI" and automatically call the correct GUI AND have access to all my child specific methods and properties (serial port settings etc..). My thought was that I didn't want to include the GUI as part of the class but maybe that is what I need to do?

P.S. What do you mean by "Preserve Run-Time Class". Where do I find this setting?

Edited by lvman
Link to comment

I suppose I could make "Add/Edit Unit GUI" as a method for "Unit" class, and this will get over written for each child class of "Unit" ("serial unit"). Then I can pass in a "Unit" object into the "Unit.Add/Edit GUI" and automatically call the correct GUI AND have access to all my child specific methods and properties (serial port settings etc..). My thought was that I didn't want to include the GUI as part of the class but maybe that is what I need to do?

It sounds like you should make a separate VI for each type of unit, that overrides a VI in the parent class. If you don't want to include the GUI directly in the class, you could develop a system where you use a set of queues or user events to pass data, or embed the VI as a subpanel. Your description does sound like a classic use case OOP.

P.S. What do you mean by "Preserve Run-Time Class". Where do I find this setting?

It's a function, not a setting, found with the other OOP functions in the palettes.

Link to comment

It sounds like you should make a separate VI for each type of unit, that overrides a VI in the parent class. If you don't want to include the GUI directly in the class, you could develop a system where you use a set of queues or user events to pass data, or embed the VI as a subpanel. Your description does sound like a classic use case OOP.

It's a function, not a setting, found with the other OOP functions in the palettes.

Thanks for the replies.

You were initially correct in that I could use the "to more specific class" vi. I was getting the error because I passed in a "unit" object that was not defined! Basically I had a "serial unit" input into my Add/Edit gui and I tried casting a "unit" to a "serial unit", but my "unit" object was not defined. I needed to make sure it was an actual "serial" unit, or create a "serial unit" object and skip the cast function. Hope that makes sense.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.