Question

I have been writing different classes lately, and I have noticed that I have inadvertently been reading / writing to them using both field and property identifiers, and I am wondering what are the pitfalls if any of doing this?

Lets use a basic class as an example:

TMyClass = class
private
  FName: string;
  FID: Integer;
public
  constructor Create(AName: string);
  destructor Destroy; override; 
published
  property Name: string read FName write FName;
  property ID: Integer read FID write FID;
end;

By field identifier I mean, for example FName and FID, and by property identifier I mean Name and ID for example.

The whole purpose of the published property is to be able to access it outside of the unit the class is written in if I am not mistaken. Which surely means the field identifiers should be used in the unit the class is written in, after all you cannot access those field identifiers outside the class.

This is where I have noticed that in some of the procedures (private or protected) I have not been using FName or FID, but instead have used the property equivalent, Name and ID - or sometimes mixed.

So far I have seen no issues, and in fact I normally would use FName and FID but like I say, have inadvertently not done so for some reason.

Is this bad practice or could it lead to something more sinister?

Thanks.

Was it helpful?

Solution

The purpose of a property is not to allow access to class data outside of the class per se.
This could be easily done by declaring your member data as public.

The purpose of properties is to facilitate good OOP.
The following points illustrate the concept.

Side effects
The main purpose of properties is to hide the implementation details of your class and allow 'side-effects' when setting properties.
This is obvious in the VCL where changing the height property will automatically change the window's appearance due to the side effects coded in the SetHeight Setter.
This is part of the OOP concept of information hiding.

These side effects are useful whether you are inside you class or not.
The other useful aspect kicks in when your class or one of its descendants changes the behavior of the property; adding a side-effect where there was none before.
If your old code inside the original class fiddles with the fields directly these side-effects will not trigger, breaking the change inside the descendant.

Rule of thumb: side effects
Always use the property, unless you explicitly want to prevent a side-effect from triggering. !!Remember getters can have side-effects as well.

Implementation hiding
Sometimes the fields are not a direct translation of their appearance in the property.
Or you may want to change the implementation under the hood, but keep the properties the same.
Again in this case you may want to hide these details in your own class as well, so that descendant classes do not break.
e.g. if you have your storage implemented as a red/black tree with pointers you want to minimize the impact to the rest of the routine when you decide to switch to an array based offset structure.

Rule of thumb: implementation hiding
Only access the fields directly in these routines that deal directly with the data.
Limit the number of those routines by putting general purpose routines in place, like: locaters, iterators etc.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top