• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 215
  • Last Modified:

A vs B ... two objects from slightly different ancestors need access to same method.. which is the best way to do this?

hopefully this is a quick question for someone.  i dont need a full explanation of how to do it, but rather your short answer (A or B below - and a reason if you feel like typing lots) to what you think is the best method of acheiving this.

i will be using a TClientDataSet in memory and creating fields at runtime to hold my data.  I will create descendants of all the TFields (eg TStringField, TIntegerField, etc) for my extra requirements.  I specifically need a new Value (Value2) property to perform in a different manner to the inherited Value property (I wont override the inherited because i need that too as it is).

In the read function for my Value2 property i need to perform some substantial processing.  My problem is that all of my descendant TFields i create (eg TMyStringField, and TMyIntegerField etc) will all use a similar procedure (MapFieldValues) inside the read function for the Value2 property.  So basically i wish my MapFieldValues procedure was part of Tfields so my descendants will all inherit it

procedure ???.MapFieldValue(var Value : string);
begin
  //perform heaps of processing
end;


TMyStringField = class(TStringField)
protected
  function GetAsString2: string;
  procedure SetAsString2(const Value: string);
public
  property Value2: string read GetAsString2 write SetAsString2;
end;

procedure TMyStringField.GetAsString2: string;
var
  temp : string
begin
  if GetValue(temp) then begin //firstly get the normal value
    MapFieldValue(result);  //used by all my descendant TFields
    CheckTags(result);
  end else Result:='';
end;

TMyIntegerField = class(TIntegerField)
protected
  function GetAsString2: string;
  procedure SetAsString2(const Value: string);
public
  property Value2: string read GetAsString2 write SetAsString2;
end;

procedure TMyIntegerField.GetAsString2: string;
begin
  result:=GetAsString; //firstly just get the normal value
  MapFieldValue(result);  {again this is used by the TMyIntegerField as well as                

                 TMyStringField}
  CheckTags(result);
end;


Question :   What is the best method to allow all of my descendant TFields to have access to the MapFieldValues procedure??  

A : Should i use Interfaces
or
B : simply change the definition of TFields itself so all my descendants inherit this procedure?  or is there a better way of doing this?

thanks for you time, and I appreaciate any kind answers no matter how small
grolsch
im new member and have assigned all my points to this....
0
grolschisgood
Asked:
grolschisgood
  • 4
  • 4
1 Solution
 
ITugayCommented:
Hi grolschisgood,

all TField descendant has events:
  OnChange
  OnGetText
  OnSetText
  OnValidate

May be you can set event handlers to the same procedure for all new created fields (TIntgerField, TFloatField....).
____
Igor
0
 
ITugayCommented:
ok, not good idea to use events, doesn't usefull in this case.
____
Igor
0
 
grolschisgoodAuthor Commented:
thanks igor for quick response.  i intend to use these events for when i hook a dbgrid to the data set.  this grid would part of the user interface for debugging program configuration, or just general snooping of data and reporting

however normal operating of the program does not have a user interface.  My client data set will only sit in memory as a buffer for incmong data from various sources.  calculations and lookups (not using the normal calc events of lookup fields cause i want these fields to be ftdata) will occur on this client data set, and eventually the values will get past to other datasets that are connected to one of several databases.

i will be using the values2 property when assigning data between this client data set and the other db connected datasets.  the return type of the property will be string or integer etc depending on the field type so that the data passes directly into a corresponding field type on the connected dataset.

sorry i wasnt clear on above exmaple cause i used the GetAsString2 method of the TIntegerField as example instead of GetAsInteger as read function for Value2 property
0
Learn to develop an Android App

Want to increase your earning potential in 2018? Pad your resume with app building experience. Learn how with this hands-on course.

 
ITugayCommented:
may be something like this?


procedure MapFieldValue(Sender: TField; var Value : string);
begin
  if Sender is TMyIntegerField then
    with Sender as TMyIntegerField do
    begin

    end
  else
  if Sender is TMyStringField then
    with Sender as TMyIntegerField do
    begin

    end
....
end;

procedure TMyStringField.GetAsString2: string;
var
  temp : string
begin
  if GetValue(temp) then begin //firstly get the normal value
    MapFieldValue(Self, result);  //used by all my descendant TFields
    CheckTags(result);
  end else Result:='';
end;




____
Igor
0
 
grolschisgoodAuthor Commented:
so you would suggest having the mapfield procedure 'owned' by the unit, as opposed to it being part of the objects?

also, my intention was to overload the procedure rather than check for different objects with the 'if Sender is TMyIntegerField' statement.  would you say that the 'if' method would be faster than overloading?

thanks again for you time
0
 
ITugayCommented:
Hi grolschisgood,

>> so you would suggest having the mapfield procedure 'owned' by the unit
yes, exactly.


I'm afraid that overload doesn't help you too much in this case.

if Sender is TMyObject then
  whith Sender as TMyObject do
  begin
  end;

would be right choice. It works fast enought, don't worry.

____
Igor
0
 
rondiCommented:
Does the MapFieldValues method differ for each class type?
0
 
grolschisgoodAuthor Commented:
thanks igor, im just playing around with this whole idea so which try your suggestion out before i make a start.

rondi, the mapfields method performs the same basic processing for each class type however it will handle different types of values depending on which class type has called it, eg string or integer.

i will leave this q open for a couple of days to get some more suggestions but so far the replys have been great
0
 
grolschisgoodAuthor Commented:
the answer is good but hasnt expanded me much on my original thinking.  i was hoping for someones opinion on using interfaces or simply recreating TFields as another approach

cheers ITugay
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

  • 4
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now