Property or Variable?

Posted by olivier.dunemann on 15-Feb-2010 04:21

Hi there,

I wonder if there is a clear rule telling us when to use a property or rather a variable?

A property is supposed to show a "state" of an object. It can have any combination of private/protected/public accessors, while a variable is either fully private/protected/public (for both its "get" and "set" accessors).

So far, I can distinguish 3 cases:

1) The state can be set without any validation:

The developer can define a property or a variable.

The variable can be public or protected, or even private with related "get" and "set" (public) methods.

2) The state can be set without any aborting validation:

The developer is invited to define a property, and to set the validation code in the "set" accessor.

3) The state might not be set if a validation fails:

The developer is invited to define a private property or variable, in conjunction with a "set" method returning TRUE if the validation succeeds or FALSE if the validation fails.

I would like to know if I'm wrong or right, or if I'm missing some important consideration or principle.

Thank you for your participation.

All Replies

Posted by Matt Baker on 15-Feb-2010 07:52

A few simple rules that I follow:

If you plan on accessing the value from outside the current class, then use a property. This is a good indication the value is a "property" and not just internal state of the object.

If you only need it inside the class, use a variable.  If no one else needs to see the value, then the value is "state" and not "property".

Your last point is also valid.  If you think you might *ever* need validation, then use a property. Properties provide a convenient place to put validation rules on setters, and bits of logic for getters.

If you might need to override it with different behavior (e.g. provide the value from a derived class), then use a property.  This is especially true for calculated values where there is no setter present, but simply a getter.

If you think the value will become part of an interface when you need to refactor, then use a property.

When *not* to use a property:

     If the getter or setter has real logic in it.  Anything more than a few lines in either the getter or setter should indicate you need to use a method and not a property.

     If you have to do signifiicant conversion of some state in order to provide the value or create an object to store the value, then use a method and not a property.  Property access should generally be fairly cheap since it is likely they will be accessed repeatedly without any sort of local caching by the calling object.  For example, the "ToString()" method is not a property since it will generally "convert" some set of internal state into a string.

Posted by Peter Judge on 15-Feb-2010 09:29

A few simple rules that I follow:

If you plan on accessing the value from outside the current class, then use a property. This is a good indication the value is a "property" and not just internal state of the object.

If you only need it inside the class, use a variable.  If no one else needs to see the value, then the value is "state" and not "property".

Type (ie just me) or class (me and my descendants)?

-- peter

Posted by olivier.dunemann on 15-Feb-2010 09:45

Thank you Matthew.

You say: "If you only need it inside the class, use a variable."

So, for you, a variable should (always) be for internal use only (inside a method, a class, a trigger, a function, an internal/external procedure).

This makes usage of variables clearer... But it also means that we should not use the possibility to define them as "public" members.

I've once read that using private variables associated with a pair of private/protected/public accessor methods offers the most flexibility (in terms of access-modes, validation code, and inheritance). It sounds good, but on the other hand we loose the implicit information that a property conveys: 'I am a state of the object'.

It's a little bit out of the scope of this discussion, but I guess that in the same document it was said that local "buffers" should also be defined and used inside methods, class,... rather than the default buffer that comes with temp-tables and "real" tables.

Posted by Thomas Mercer-Hursh on 15-Feb-2010 11:17

Properties are really just a very simple way to implement the same thing as a variable and associated accessor methods.  In the simplest case, i.e., no actual code required, one can define the variable and make it read/wrtie, read-only, or write-only all in a single line, whereas the accessor methods would take at least three lines each to be readable.  So, I would say strong preference for using a property over a variable and accessor methods for any knowledge attribute of the class which is publicly available.  Generally, such attributes will only have a limited amount of logic associated with them.  E.g., internally the class might compute and store things in radians, but the external interface was in degrees, so a conversion is  required going in and out, but there is no real behavioral implications.

Now, of course, not everything is a property and not everything is public.  Variables are appropriate for internal state that is not publicly visible including cases, like the degrees/radians example, where the internal representation is different from the external one.  E.g., you might have an address represented as separate fields internally and then have an externally visible property which is the address composed into lines.  FWIW, a reason to do that would be to respect differing national standards on how the address should be composed out of its parts.

And, of course, anything that is behavior, even if it has associated state, is a method.

Posted by olivier.dunemann on 16-Feb-2010 02:04

So, in conclusion, variables should be for internal use (private or protected), while properties are for public exposure.
If a developer is about to turn a variable into a public member, he should consider to convert it into a property.

Thank you for your comments

Posted by Admin on 16-Feb-2010 02:10

So, in conclusion, variables should be for internal use (private or protected),

In our style guide there needs to be a really good reason (documented in a comment) for a protected variable as well (private are o.k.).

If a developer is about to turn a variable into a public member,

he should consider to convert it into a property.

 

Again in our style guide there is no option. It has to be a property then.

Posted by Matt Baker on 16-Feb-2010 08:02

There are very valid reasons for using protected and even public variables.  For example, in performance critical classes using variables is a little cheaper since you don't have the method call overhead associated with the getter/setter.  But this violates encapsulation and is a very rare case.  So don't do it without a very good reason.

For protected variables it isn't uncommon to expose them to child classes.  For example, you may have a user control which has some UI which you extend with another class.  You may not want to expose one of the fields of the UI control to the world, but it is completely valid to make it protected and expose it to child classes to access.

Posted by Peter Judge on 16-Feb-2010 08:05

For example, in performance critical classes using

variables is a little cheaper since you don't have the method call

overhead associated with the getter/setter.

It's my understanding that there is no such overhead in the ABL. A property without a getter/setter implementation performs the same as a variable.

-- peter

Posted by Admin on 16-Feb-2010 08:49

pjudge schrieb:

For example, in performance critical classes using

variables is a little cheaper since you don't have the method call

overhead associated with the getter/setter. 

It's my understanding that there is no such overhead in the ABL. A property without a getter/setter implementation performs the same as a variable.

Excellent!

But as both of you are carrying the PSC employee badge on PSDN, I hope that you can come up with a single common understanding, maybe even in sync with the actual implementation of the AVM/ABL compiler. It would be lovely if then you could share that with the community...

Never the less, a potential performance gain must be very significant for me to change our coding standards. A developers performance when maintaining code is also of significant importance and so clarity of code is a criteria as well.

Posted by Admin on 16-Feb-2010 09:24

For protected variables it isn't uncommon to expose them to child classes.  For example, you may have a user control which has some UI which you extend with another class.  You may not want to expose one of the fields of the UI control to the world,

A protected property would do exactly that!

but it is completely valid to make it protected and expose it to child classes to access.

Using a variable the child classes can NEW a new control without letting the base class know... What if the base class needs to subscribe to events of those controls? The SETter of the property would be an excellend place for that.

In cases like the one described, I'd probably use a PROTECTED property where the SET accessor is only PRIVATE. That gives access to those referenced objects without the ability to replace the instance.

Posted by Matt Baker on 16-Feb-2010 09:54

Ahhh, the age old debate.  properties vs. variables.  There are as many different opinions as there are hands on people.  A lot of it boils down to "what is right for me/us".  In some cases you have to use properties such as with interfaces, but in other cases there is no "wrong" answer.

Peter is right.  There is no performance difference for ABL between using a property with empty getter/setter or using a variable.  There is a difference in performance if the setter/getter is non-empty.  There is a small difference when using .net properties, but only because it goes over the bridge.  But like I said, unless it is performance sensitive and you can prove there is a difference in performance between implementations, don't let that be a deciding factor.

Posted by olivier.dunemann on 16-Feb-2010 10:47

mbaker wrote:

Ahhh, the age old debate.

Mmm, this is what I feared...

Ok, let's take a concrete example. I'm setting up a "Logging Service", which is initialized at startup, and that should be easily invoked by any Business Component.
What is the best practice... if one exists?

- Define, in the "Business Component" base class, a... variable ...that references this service;
- Define, in the "Services Manager" a:
  * read-only property referencing this service;
  * generic method taking as input parameter a ServiceName, and sending back the related Progress.lang.object
- Something else?

It comes to me another example, taken from John Sadd's "Class-based implementation of the OERA". With all my respect for (and thank to) John, if you look at the BusinessEntity base class, you can see 3 protected variables:
  DEFINE PROTECTED VARIABLE hdsDataset     AS HANDLE NO-UNDO.
  DEFINE PROTECTED VARIABLE srvdatacontext AS base.srvdatacontext.
  DEFINE PROTECTED VARIABLE dataAccess     AS base.dataaccessobject NO-UNDO.
Forget about the "srvdatacontext" (which should be replaced, in my sense, by a real Context Service), but what about the "hdsDataset" and "dataAccess"? In my opinion, they should rather be properties.

That can sound quite futile but I really want to give clear guidelines to our developers.

Posted by Admin on 16-Feb-2010 11:18

mbaker schrieb:

Ahhh, the age old debate.  properties vs. variables.  There are as many different opinions as there are hands on people.  A lot of it boils down to "what is right for me/us".  In some cases you have to use properties such as with interfaces, but in other cases there is no "wrong" answer.

Not every developer - especially when starting with OO - tend's to be in the mood or position to debate such kind of things. And for the sake or maintainability a team should develop in a reasonable consistent way.

That's why every team should have it's standards, manifested by a subset of team-members that did that debate and take responsibility for the consiquences.

Posted by Thomas Mercer-Hursh on 16-Feb-2010 11:21

Indeed!  It would take some real arm twisting before I could justify a public data member.  Let's see some test results.

Note, in particular, that a 10% improvement in something that only takes a microsecond is not material to the performance of the application unless one is doing it millions of times ... and if one is doing it millions of times, one might guess that one hadn't properly decomposed the problem space.

Posted by Thomas Mercer-Hursh on 16-Feb-2010 11:36

Ahhh, the age old debate.  properties vs. variables.  There are as many  different opinions as there are hands on people.  A lot of it boils down  to "what is right for me/us".

I think there is an important distinction to be made.  If one searches around the web, one can indeed find a lot of different opinions ... even people who think that public data members are just a fine thing.  But, I don't think one should translate that into "everything is OK because someone, somewhere thinks it is OK".  Instead, I think it means that one needs to establish personal standards and think hard about what is right according to those standards and code accordingly.  It is even worth accepting a certain amount of performance penalty in most cases if it gives you a cleaner implementation.  If one isn't prepared to think all of this out oneself, then one has to pick what Authority one is going to pay attention to for guidance, but one should do so carefully and even selectively rather than blindly.

Specifically, in the present case, one needs to be very clear about what is exposed and what isn't.  That which is exposed should be the minimum.  Really think about taking an area of responsibility and encapsulating it in the object and how little other objects need in order to use the knowledge and behavior in that responsibility.  Just because it is easy to make something available and it is convenient to just reach in there and grab it doesn't mean that it is right.  One should be just as careful about minimizing coupling in generalization hierarchies as between unrelated objects.

More in this vein here http://www.cintegrity.com/content/Object-Oriented-Design-Principles

Posted by Admin on 16-Feb-2010 11:43

Instead, I think it means that one needs to establish personal standards and think hard about what is right according to those standards and code accordingly

I take that as a team's personal standard rather than a developer's personal standard, right?

Posted by Thomas Mercer-Hursh on 16-Feb-2010 11:47

Deleted ... stupid FF is playing crashing tricks.

Posted by Thomas Mercer-Hursh on 16-Feb-2010 11:50

You might want to look at this http://www.cintegrity.com/content/Patterns-Managing-Relational-Data-OOABL before taking those whitepapers as a style guide.  There will be a much more detailed piece on this topic out soon.

Posted by Thomas Mercer-Hursh on 16-Feb-2010 11:52

Yes, one certainly wants consistency within the shop.  Hopefully, that consistency represents the best insight of the combined minds rather than the lowest common denominator, though.

Posted by jquerijero on 16-Feb-2010 17:49

- Property is good also even if it is only used internally or declared as private. Let say setting variable A requires that variables B and C should also change. Using a property in this case if preferrable. This falls in line with the "single location" update principle just make sure that whatever your doing in inside the setter and getter is not time consuming. In this case, you always refer to the property even inside the class that defines it. Again, the setter/getter has to be fairly fast.

- Like you mentioned, when validation is required, a property is a better choice. With custom event now supported in 10.2B, you can easily expose events like MyPropertyChanging and MyPropertyChanged. You can not have this with a public variable.

Posted by whenshaw on 18-Mar-2010 13:07

    One last comment regarding the performance question that came up  during this thread. We recently did some formal performance testing to  compare accessing a variable to accessing a property. The results were  in line with what has been stated in the thread. When the property  accessors had no implementations, the differences were very small.  Often, but not always, accessing the property was 1 or 2% slower than  accessing the variable, with this relationship reversed on a few of the  runs.

    We also compared properties whose accessors have  implementations against methods that have the same code (e.g., a  property whose SET just assigns the input value to the property, vs.  calling a method that takes a single input parameter and assigns its  value to a private variable). On these tests the property access was  usually also slower by 1 - 2%, but sometimes the difference was as much  as 5% slower than executing the comparison method.

This thread is closed