Static?

  • Thread starter Thread starter Bruno Rodrigues
  • Start date Start date
B

Bruno Rodrigues

Hi

In a class with simple methods like:

Products.Insert(string name, string desc)
Products.Update(int id, string name, string desc)
Products.Delete(int id)

What is better? Static or common methods? This objects do not need
instances.
I have a lot of classes, and my only fear is the cost.

Thanks,
Bruno Rodrigues
 
My personal feeling is that if you are designing classes like this, they
start to look very much like procedural function libraries. Are you sure you
want to bypass the benefit's of an OO language in this way?

The methods you have created look like they might wrap a database table. I
would ask the question, where are you storing the names, desc, id etc, that
you are passing into these methods? If they are just a loose bag of
simple-type variables, I would suggest that you would be much better of
moving them into your Products class (and renaming is Product).

Maybe you know all this, and have some good reason to build a class like
this (mainly, its a stateless class, and it might be useful in situations
where you have to be stateless). Even so, I would be inclined to avoid
classes that are entirely static.

Nick Holmes.
 
In this particular case, I would probably create static methods.

Regards,

Jose Luis Manners, MCP
 
I doubt there's much in it, but it would really depend on the ratio of
objects creations to method calls if you went the normal route.

If you have constraints, then so be it, but I think performance is far too
often worried about at the expense of good design in the first place.

BTW, did you think of using some kind of code generation for this - those
really do look like db wrappers, and they really lend themselves to that.

Nick.
 
Nick Holmes,

This is a kind of problematic project. It's big and there is no time to
design the classes from scratch. Having this in mind, my procedural
libraries are better this way, or with static methods? What is better in
performance?

Thanks for the help
Bruno Rodrigues
 
Procedural methods are much faster in that they don't need an instance
in order to do work. Even if you do have a Project class, there still has
to be a set of static methods to get constructed instances, else the user
can do all sorts of data spoofing by creating bogus Project instances
and then calling methods on them.

Stick with your static method approach. It'll save you some time now,
and later if you want to add instance functionality, you can simply write
a Project class that is returned by static methods on the Projects class.
This is a simple class factory design, works well, and provides great
performance.
 
My personal feeling is that if you are designing classes like this, they
start to look very much like procedural function libraries.
What do you mean?
Are you sure you
want to bypass the benefit's of an OO language in this way?
What OO benefits?
 
The premise was, that the class would consist of only static methods - it
would do everything it could do with out any instance of the class. The
particular examples given:

void Products.Insert(string name, string desc)
void Products.Update(int id, string name, string desc)
void Products.Delete(int id)

are directly equivalent to C functons of the form:

void Products_Insert(string name, string desc);
void Products_Update(int id, string name, string desc);
void Products_Delete(int id);
What OO benefits?

1) Encapsulation: not present, the class has no data members and does not
aggregate the data.
2) Protection: not present, the data is completely at the mercy of the rest
of the application
3) Polymorphism: not possible (we have no instance of Products that to
reference any subclasses)
4) Inheritance: hardly meaningful anymore, really.

Hope that helps,
Nick.
 
Nick Holmes said:
My personal feeling is that if you are designing classes like this, they
start to look very much like procedural function libraries. Are you sure you
want to bypass the benefit's of an OO language in this way?

I've heard this mentioned before but no one will ever answer me. What is
not OO about Static/Shared members and what benefit are you passing up?
What OOP benefit do you loose if you use Static/Shared methods? Aren't some
things, from an OO, better represented as belonging to the class than a
specific instance of it?
The methods you have created look like they might wrap a database table. I
would ask the question, where are you storing the names, desc, id etc, that
you are passing into these methods? If they are just a loose bag of
simple-type variables, I would suggest that you would be much better of
moving them into your Products class (and renaming is Product).

Maybe you know all this, and have some good reason to build a class like
this (mainly, its a stateless class, and it might be useful in situations
where you have to be stateless). Even so, I would be inclined to avoid
classes that are entirely static.
Why? And how do you decide what point is 'too' much static stuff?

If I seem conentious, I assure you I'm not. I just see this argument come
up frequently and I don't understand it.. I could well be uninformed but I
have never heard a compelling (or even decent) arguement about them and
would love to hear one. I mean the Framework has many Static classes ie
Directory as well as Instance classes DirectoryInfo.
Nick Holmes.
--
W.G. Ryan MVP Windows - Embedded

http://forums.devbuzz.com
http://www.knowdotnet.com/dataaccess.html
http://www.msmvps.com/williamryan/
 
I am not suggesting static members are not inherently non-OO. Its this case
where you build a class that will represent many "instances", but is in fact
100% static methods. It relies on external storage of its data (thus
abandoning Encapsulation and giving up any chance of Protection). As there
are never any instances of the class, Polymorphism is not possible, and
Inheritance is limited.

Let me say this, if you dont think these are serious losses, why aren't you
still coding in C?

Just so I dont get branded a some kind of anti-static zealot, I will say
they are of course useful in more normal design, and if the loss of the
facilites given above is not an issue (like for Directory), then crack on.
Why? And how do you decide what point is 'too' much static stuff?

When the class is 100% static, yet really is intended to repesent many
instances, I would say chances are good that the design is bad, and I would
seek a very good justification to doing it this way.

Nick.
 
Hey Nick

If you expose an object having the required instance methods through a static method on another type (i.e. a singleton pattern) then you would be able to use inheritance and polymorphism for this object because you can always replace the object instance with another instance (of an inherited type) without the client knowing it. This will give you the benefit of having static methods in a sort of OO way

However, I agree with you that static methods are similar to global methods in C which is not good

Regards, Jakob.
 
Justin Rogers said:
Procedural methods are much faster in that they don't need an instance
in order to do work. Even if you do have a Project class, there still has
to be a set of static methods to get constructed instances, else the user
can do all sorts of data spoofing by creating bogus Project instances
and then calling methods on them.

Stick with your static method approach. It'll save you some time now,
and later if you want to add instance functionality, you can simply write
a Project class that is returned by static methods on the Projects class.
This is a simple class factory design, works well, and provides great
performance.

If your methods are going to perform inserts/updates/deletes into a
database, you should not worry about the cost of allocating an instance, nor
about the cost of an instance method vs. a static method. The performance
will be dictated by the quality of the DB layer that you are accessing, not
by the thin layer that you put around it.

So, I would recommend the exact opposite: create a Product class and
implement the Insert/Update/Delete as instance methods. In short, start with
a good OO design, and worry about performance later (and do it based on real
data provided by a perf analysis tool, don't rely on a priori assumptions).

Bruno.
 
If your methods are going to perform inserts/updates/deletes into a
database, you should not worry about the cost of allocating an instance, nor
about the cost of an instance method vs. a static method. The performance
will be dictated by the quality of the DB layer that you are accessing, not
by the thin layer that you put around it.

So, I would recommend the exact opposite: create a Product class and
implement the Insert/Update/Delete as instance methods. In short, start with
a good OO design, and worry about performance later (and do it based on real
data provided by a perf analysis tool, don't rely on a priori assumptions).

This goes against hard performance evidence used to develop high capacity
applications like the ASP .NET Forums system. The logic of constructing a
Product object to do something like a Delete is just not smart. Nor does
constructing a Product object requiring that such an ID be passed into the
constructor. Some portions of the object have to be immutable and so those
have to be specified in a constructed phase.

Factories offer the ability to do micro-caching (very important for retrieving
view
only versions of the underlying data), and they enforce a single class instance
per
database record in the back-end. You simply can't achieve all of these
performance
related goals using instances, nor is it the right way if you want your
application to
scale, else we would have used that instead of statics in the ASP .NET Forums
system.
 
Justin Rogers said:
assumptions).

This goes against hard performance evidence used to develop high capacity
applications like the ASP .NET Forums system. The logic of constructing a
Product object to do something like a Delete is just not smart. Nor does
constructing a Product object requiring that such an ID be passed into the
constructor. Some portions of the object have to be immutable and so those
have to be specified in a constructed phase.

I agree that it is a bit silly to construct an object to execute a Delete.
It makes more sense for Update and Insert. But I find it surprising that
micro optimizations like these (avoiding one object allocation, replacing
instance methods by static methods) make a real difference, unless you have
an extremely fast data access layer (not a SQL DB) behind it. What is your
persistence layer?
Factories offer the ability to do micro-caching (very important for retrieving
view
only versions of the underlying data), and they enforce a single class instance
per
database record in the back-end. You simply can't achieve all of these
performance
related goals using instances, nor is it the right way if you want your
application to
scale, else we would have used that instead of statics in the ASP .NET Forums
system.

I agree 100% with using factories and caching. But you can still expose
instances, as long as you expose them as immutable instances.

Bruno.
 
Justin Rogers said:
assumptions).

This goes against hard performance evidence used to develop high capacity
applications like the ASP .NET Forums system. The logic of constructing a
Product object to do something like a Delete is just not smart. Nor does
constructing a Product object requiring that such an ID be passed into the
constructor. Some portions of the object have to be immutable and so those
have to be specified in a constructed phase.


Justin, is this performance information available? It would be interesting
to look at.
 
I don't doubt there is performance benefit from doing this, but i can't help
but think its insignificant compared to the loss of maintainability that
occurs. In the original example,

Products.Insert(string name, string desc)

Product only seems to have a name and a desc, but in real world SOP/POP/ERP
system, it would have many more fields. Other typical business objects like
Sales Orders or Purchase Orders typically have sub collections of line
items, too. Anyway, I contented that having Products.Insert() et al with
20-50 parameters is hugely difficult to maintain. For example, if you need
to add one field thats used in one small part of your business logic, all
your code will need to be touched (or you start writing loads of
almost-the-same methods to accomodate various needs, which also gets you in
to maintenance issues down the line).

The most obvious way to address this is to encapulate them all in a class.
Once you've encapsulated them in a class, why not make the methods normal
instance methods?

OK, ASP.NET applications are stateless, and that implies lots of object
creation and destruction. But isn't it insignificant compared to the general
cost of running up a page and checking a cache or visiting a database?

Nick.
 
Product only seems to have a name and a desc, but in real world SOP/POP/ERP
system, it would have many more fields. Other typical business objects like
Sales Orders or Purchase Orders typically have sub collections of line
items, too. Anyway, I contented that having Products.Insert() et al with
20-50 parameters is hugely difficult to maintain. For example, if you need
to add one field thats used in one small part of your business logic, all
your code will need to be touched (or you start writing loads of
almost-the-same methods to accomodate various needs, which also gets you in
to maintenance issues down the line).

The static methods can and should be refactored after about 4 fields are added.
At that point they should take a Product object, but remain static. The static
methods View/Insert/Update/Delete should all be there. Some of the methods
will take a Product others will take strongly typed data, depending on what you
have available. Generally Delete will take an int ID for instance, yes you lose
the
ability to change to Guid or a FooId, and you can be the guy buying new machines
every 6 months because perf is so bad if you want that flexibility. Many Update
operations are only on single fields or a couple of fields at a time as well, so
many
Update overloads are probably going to be used. Insert is always sticky,
because
you can either pass in an immutable Product class (aka, you have no id for it
yet),
or you can simply consume stack space and pass in a bunch of parms.
The most obvious way to address this is to encapulate them all in a class.
Once you've encapsulated them in a class, why not make the methods normal
instance methods?

As I mention above, even after you encapsulate them in a class, better to keep
the
methods static in most cases and have them eat a Product, rather than allow
Product to do any real business.
OK, ASP.NET applications are stateless, and that implies lots of object
creation and destruction. But isn't it insignificant compared to the general
cost of running up a page and checking a cache or visiting a database?

Not insignificant when you start talking about caching (50-100 views of the same
object with only a single hit to the DB), extensive role checking (do you really
want the role logic to be encapsulated inside of a class instance), and other
features of static methods that are simply indispensable (some of which we've
hit on previously, others we have not).

As for performance numbers on static/instance usage, I challenge you to run them
in your own scenarios rather than rely on a stock piece of paper. Many things
will
affect the outcome, including size of object instances, methods per static
class,
memory access speed, database access speed, database on the same vs separate
machines. It is clear to me that calling Insert(string, string) is going to be
faster than
constructing an object, passing it in, reading the parameters off, etc...
 
Justin Rogers said:
The static methods can and should be refactored after about 4 fields are added.
At that point they should take a Product object, but remain static. The static
methods View/Insert/Update/Delete should all be there. Some of the methods
will take a Product others will take strongly typed data, depending on what you
have available. Generally Delete will take an int ID for instance, yes you lose
the
ability to change to Guid or a FooId, and you can be the guy buying new machines
every 6 months because perf is so bad if you want that flexibility. Many Update
operations are only on single fields or a couple of fields at a time as well, so
many
Update overloads are probably going to be used. Insert is always sticky,
because
you can either pass in an immutable Product class (aka, you have no id for it
yet),
or you can simply consume stack space and pass in a bunch of parms.


As I mention above, even after you encapsulate them in a class, better to keep
the
methods static in most cases and have them eat a Product, rather than allow
Product to do any real business.


Not insignificant when you start talking about caching (50-100 views of the same
object with only a single hit to the DB), extensive role checking (do you really
want the role logic to be encapsulated inside of a class instance), and other
features of static methods that are simply indispensable (some of which we've
hit on previously, others we have not).

As for performance numbers on static/instance usage, I challenge you to run them
in your own scenarios rather than rely on a stock piece of paper. Many things
will
affect the outcome, including size of object instances, methods per static
class,
memory access speed, database access speed, database on the same vs separate
machines. It is clear to me that calling Insert(string, string) is going to be
faster than
constructing an object, passing it in, reading the parameters off, etc...

Why in the world would the methods per static class matter to performance?
And how would the amount of memory access differ if the same data need to be
accessed?
 
Back
Top