Jump to content

"force" delegation? <no idea what to call this topic>


Recommended Posts

Sorry, this topic title is awful, but I will explain what I want to do here and look for feedback and suggestions.

 

I have a bunch of different record types, each one has a "format for file" must override method. So my heirarchy looks like this:

 

Record base class, with record children A, B, C, D, E.

 

I have a method to send a record to my logger. I want to be able to send A, B, C to this logger, but I do not want to be able to send D or E. If D or E is used should always be passed into C first. When C writes to a file, it calls D or E's format for file VI. Now, my initial thought was to pull D and E outside this inheritance hierarchy, that way they could not be sent via the "send record" method. But, these classes still need a way to be formatted for a file, so I end up creating another class hierarchy with seemingly duplicate behavior. This may be correct, but I was curious if there is a more straight forward way around this.

Link to comment

Their own overriden method will be called inside Cs method, but they do not directly use C's method. This may clarify what I'm trying to do. I have an existing structure in C/C++

 

typedef struct {//edited some stuff out to be more concise for this post    union    {        struct         {            fat_data_record_TAG id[TSNCHN];        } FAT;        struct         {            fat_data2_record_TAG id[TSNCHN];        } FAT2;        struct         {            gag_record_TAG gi;        } GAG;		struct		{			int RecordNumber;	        int	EventCode;	        int	CurrentLoadCondition;	        int	CurrentLoad;	        int	GoingToLoad;	        char Desc[TSLDES+1];			static_data_record_TAG sd[TSNCHN];		} STA;        struct        {	        int RecordNumber;            int	EventCode;            int	CurrentLoadCondition;            int	CurrentLoad;            int	GoingToLoad;            char Desc[TSLDES+1];            char ItemCode[TSNCHN][TSLITM+1];                 } RDB;    } Data;} SpectrumData_TAG;

Unions don't exist in LabVIEW obviously, so I was going to replace the union with a single, DataRecord member, the type of which would be injected. Now, I have classes FAT, FAT2, GAG, STA and RDB, one of which would be injected at run time. The problem is I don't want FAT, FAT2, GAG, STA, or RDB to be sent to my logger alone, they need to be inside the SpectrumData_TAG class. However, because SpectrumData_TAG along with FAT, FAT2, GAG, STA and RDB are all DataRecords, the method to "send new record" will accept them all...there is no protection from a FAT, FAT2 etc from being sent. So, I assumed by breaking up the inheritance heirarchy, I could protect from this. But, then I lose the fact that FAT, FAT2, GAG, STA, and RDB all need to have a method which is defined in the DataRecord base class. So I end up duplicating that.

 

Clear as mud?

Link to comment

Bit of a brain fart I think...

I believe you're right James.

 

I should make these a child class of "C" or SpectrumData_Tag. Just queue up either Fat, Fat2 etc and all the data I edited out would be in the parent class (SpectrumData_Tag), because it pertains to all children types. I think the problem came from forcing the existing structure layout into my OO architecture.

 

But, the problem then becomes, they could queue up SpectrumData_Tag itself, which is relatively meaningless; it needs to have the associated data from Fat, Fat2, GAG, etc. I suppose this isn't that big a deal though. 

Edited by for(imstuck)
Link to comment
However, because SpectrumData_TAG along with FAT, FAT2, GAG, STA and RDB are all DataRecords...

 

I think this may be your problem. I'd tackle it like so:

 

class SpectrumData{    public virtual DoSomething();}// Each type inherits from the SpectrumData classclass FAT : SpectrumData{    // Implement the must-override    public DoSomething();}// Other implementations...class FAT2 : SpectrumData;class GAG : SpectrumData;class STA : SpectrumData;class RDB : SpectrumData;// Note no inheritanceclass SpectrumData_TAG{    SpectrumData Data;        DoSomething();}SpectrumData_TAG::DoSomething(){    // The TAG class delegates to the appropriate implementation of the contained type.    Data.DoSomething();}

 

That is the TAG class wouldn't share the same ancestor as each individual type. I'm assuming there's a good reason you're looking to preserve this union-like behavior.

  • Like 1
Link to comment

That is the TAG class wouldn't share the same ancestor as each individual type. I'm assuming there's a good reason you're looking to preserve this union-like behavior.

Thanks, I'll digest that in a minute. The reason for this behavior is because they are logging to a binary file, and we are trying to match that file in our new system so existing parsers will work. Each record defines some common data for the test, but the data in the record itself can only be one type (FAT, GAG, etc). That is the use of the union in this case. I felt that lends itself to injecting the proper data type for a test, into a single member variable at runtime depending on the test type, and scrapping the union.

Edited by for(imstuck)
Link to comment

After reviewing this, I think it gets me pretty close to what I want but not exactly. This is because there are other "Tag" structures/classes that need to be written to a file, also. The DoSomething method is flattening these particular classes to be written to a binary file. I am almost feeling that I need interfaces, so I can have the "FileWritable" interface, with a method FlattenToFileData() which would allow me to separate the inheritance heirarchies but still enforce this method. For the time being, I have broken out the inheritance heirarchies as you suggested (Tag separate from data), and in each one have put a must override, FlattenToFileData() method. It's a bit redundant but will do what I want.

Link to comment
  • 2 weeks later...

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.