are getters/setters a must?

  • Thread starter Thread starter Ben
  • Start date Start date
B

Ben

I have a small argument with a co-worker about proper design, i wanted
to get some more feedback:

we are designing an object model for a client/server system using c-
sharp -- one of the classes is "Client", it holds properties such as
'computerName', 'OSType', 'LastScanDate', etc.

it has a ton of properties (maybe ~40 as of now) all stored in a sql
table row. we also have other similar classes that will have many
properties...

my plan was to write the object so that it has an internal DataRow
variable to hold the information and use a generic GetPropertyValue
and SetPropertyValue to allow the programmer (me, in this case) to
update the object. I also want to include a Save() function, which
will verify the variables are valid and if so, it'll commit the row to
the DB.

This seems more efficient to me and keeps the code cleaner... if we
ever add more fields to the table, it'll be a matter of just verifying
them (if needed) in the Save function. Also if i really want to
verify a value upon setting it, i can put some switch statement inside
the SetPropertyValue that will do the check for a certain field.

He disagrees and wants a setter/getter for each property and says it's
the only proper way for object-oriented programming.

Can anyone offer some opinions on the matter? I've used APIs before
from Microsoft that seem to have some properties exposed, but a lot of
them were accessed via generic functions like Get/Set PropertyValue.

Thanks!!
 
It depends on what kind of 'properties' you're talking about. I'd ask
myself these questions:

- Will property names change over time?
- Will properties be added/removed often over time?
- Do the users of your program need to add/remove/change properties?
- Can you write a lot of generic code, regardless of which particular
property you're dealing with?

If any of these comes up 'yes', you can probably do without get/set
('real') properties. A total of 40 properties sounds like some of
these might come up 'yes'.

I wouldn't dare say too much more about it without some examples of
'properties' you're dealing with.

Regards,
Jeroen
 
Ben said:
I have a small argument with a co-worker about proper design, i wanted
to get some more feedback:

we are designing an object model for a client/server system using c-
sharp -- one of the classes is "Client", it holds properties such as
'computerName', 'OSType', 'LastScanDate', etc.

it has a ton of properties (maybe ~40 as of now) all stored in a sql
table row. we also have other similar classes that will have many
properties...

my plan was to write the object so that it has an internal DataRow
variable to hold the information and use a generic GetPropertyValue
and SetPropertyValue to allow the programmer (me, in this case) to
update the object. I also want to include a Save() function, which
will verify the variables are valid and if so, it'll commit the row to
the DB.

This seems more efficient to me and keeps the code cleaner... if we
ever add more fields to the table, it'll be a matter of just verifying
them (if needed) in the Save function. Also if i really want to
verify a value upon setting it, i can put some switch statement inside
the SetPropertyValue that will do the check for a certain field.

He disagrees and wants a setter/getter for each property and says it's
the only proper way for object-oriented programming.

Can anyone offer some opinions on the matter? I've used APIs before
from Microsoft that seem to have some properties exposed, but a lot of
them were accessed via generic functions like Get/Set PropertyValue.

I would generally prefer to have "real" properties:

1) It enforces only valid property names at compile time
2) It enforces type-safety for the different values at compile time
3) It's much neater for validation etc than having a big switch/case
statement
4) It allows for different access levels, inheritance/polymorphism at a
finer grained level
5) It's usually easier to debug, IME.

By the way, C# 3 makes simple properties a lot easier to cope with,
using automatic properties.

That said, I suspect you may well be able to get away with less code
just using a lookup. I'd probably go for the "purer" way of using
properties, but I wouldn't argue for too long about it either way.
 
I would generally prefer to have "real" properties:

1) It enforces only valid property names at compile time
2) It enforces type-safety for the different values at compile time
3) It's much neater for validation etc than having a big switch/case
   statement
4) It allows for different access levels, inheritance/polymorphism at a
   finer grained level
5) It's usually easier to debug, IME.

By the way, C# 3 makes simple properties a lot easier to cope with,
using automatic properties.

That said, I suspect you may well be able to get away with less code
just using a lookup. I'd probably go for the "purer" way of using
properties, but I wouldn't argue for too long about it either way.

--
Jon Skeet - <[email protected]>http://www.pobox.com/~skeet  Blog:http://www.msmvps.com/jon.skeet
World class .NET training in the UK:http://iterativetraining.co.uk- Hide quoted text -

- Show quoted text -

I would tend to agree, If you've got 40 odd fields and that's not
going to change often, then I'm with Jon, but if you need uber
flexibility you could consider the following. Depending on your
validation needs you could very easily put all the detail into a
config file.

Silly example but something like:

<id ="1" field name ="LastScanned" type="System.DateTime"
required="false">
<validate minvalue="01\01\2000"/>
</field>
<id = "2" field name ="OSType" type="System.int32"
enum="MyApp.OSTypes">
<validate enumcontains="true"/>
</field>
</field>
<id = "3" field name ="Name" type="System.string">
<validate maxlength ="50"/>
</field>

You then read all the field info in at start up bung them in a
hashtable (perhaps create a field class and populate the various bits)
and in your setvalue, a) retrieve the field by name (or an ID). If it
doesn't exist, throw exception, else get the field object and pass
that with the new value to a generic validator that understands the
validation rules defined in the validate section. For OSType I've gone
for an enum, but it could just as easily be a table name with look ups
or a web service address, etc. Because the type is listed you can do
a cast to ensure types are adhered to.

There are pro's and con's to the above, it really depends on how
frequently you're going to be adding/deprecating/renaming fields. It
does offer some flexibility in that you can expand the above to
include UI information for example. Should this be a combo or a
listbox? But there's an overhead setting it up. I've used similar
schemes successfully, but we needed such a high degree of
configurability it just made sense.
 
I would tend to agree, If you've got 40 odd fields and that's not
going to change often, then I'm with Jon, but if you need uber
flexibility you could consider the following. Depending on your
validation needs you could very easily put all the detail into a
config file.

Silly example but something like:

  <id ="1" field name ="LastScanned" type="System.DateTime"
required="false">
    <validate minvalue="01\01\2000"/>
  </field>
  <id = "2" field name ="OSType" type="System.int32"
enum="MyApp.OSTypes">
    <validate enumcontains="true"/>
  </field>
  </field>
  <id = "3" field name ="Name" type="System.string">
    <validate maxlength ="50"/>
  </field>

You then read all the field info in at start up bung them in a
hashtable (perhaps create a field class and populate the various bits)
and in your setvalue, a) retrieve the field by name (or an ID). If it
doesn't exist, throw exception, else get the field object and pass
that with the new value to a generic validator that understands the
validation rules defined in the validate section. For OSType I've gone
for an enum, but it could just as easily be a table name with look ups
or a web service address, etc.  Because the type is listed you can do
a cast to ensure types are adhered to.

There are pro's and con's to the above, it really depends on how
frequently you're going to be adding/deprecating/renaming fields. It
does offer some flexibility in that you can expand the above to
include UI information for example. Should this be a combo or a
listbox? But there's an overhead setting it up. I've used similar
schemes successfully, but we needed such a high degree of
configurability it just made sense.- Hide quoted text -

- Show quoted text -

Thanks a lot to all of you... i really appreciate the insight you
shared!! Our fields will stay constant for the most part, so i guess
i will let majority rule and add a getter/setter for each value :)
 
Ben said:
I have a small argument with a co-worker about proper design, i wanted
to get some more feedback:

we are designing an object model for a client/server system using c-
sharp -- one of the classes is "Client", it holds properties such as
'computerName', 'OSType', 'LastScanDate', etc.

it has a ton of properties (maybe ~40 as of now) all stored in a sql
table row. we also have other similar classes that will have many
properties...

my plan was to write the object so that it has an internal DataRow
variable to hold the information and use a generic GetPropertyValue
and SetPropertyValue to allow the programmer (me, in this case) to
update the object. I also want to include a Save() function, which
will verify the variables are valid and if so, it'll commit the row to
the DB.

This seems more efficient to me and keeps the code cleaner... if we
ever add more fields to the table, it'll be a matter of just verifying
them (if needed) in the Save function. Also if i really want to
verify a value upon setting it, i can put some switch statement inside
the SetPropertyValue that will do the check for a certain field.

He disagrees and wants a setter/getter for each property and says it's
the only proper way for object-oriented programming.

Using properties will make the code both more type safe and more
flexible.

BTW, I also doubt that having the data-carrying functionality and
the load/save functionality in the same class may be mixing
responsibilities too much.

Arne
 
Back
Top