Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to decide between C# static and non-static methods?

[Edit]

My original-question was "Why to decide between static and non-static? Both do the same..."

Unfortunately it was edited to a C#-specific question what I really wanted to avoid.

So, let me do some additions:

When I say interface, I don't mean the C#-keyword-interface but what I understand something like a C++-interface: A set of well defined functions to operate with my object. When saying weaken my interface, I mean I have different functions (static/non-static) that do the same thing. My interface is not well defined anymore when there are different functions to do the same thing.

So, as Bob the Janitor posted, I can implement a Validate()-function

Document.Validate(myDocumentObject);    

but also

myConcreteDocumentObject.Validate();

To get back to my Copy()-example one could implement Copy() like

myConcreteDocument.Copy(toPath);

but also

Document.Copy(myConcreteDocumentObject, toPath)

or

Document.Copy(fromPath, toPath)

when I think of a folder that contains all the files belonging to my Document (in this case I'm not dependent of a concrete instance - but I'm dependent from other things :)).

In general I'm talking about static methods not static classes (sorry, if I forgot to mension).

But as Anton Gogolev said I think my Document class is not a good example and not well designed so I think I will have to have a look at the Single Responsibility Principle.

I could also implement some kind of ManagerClass that operates with my DocumentClass:

For example:

myDocumentManagerObject.Copy(myConcreteDocumentObject, toPath);

or

myDocumentManagerObject.Copy(myConcreteDocumentObject, toPath);

but if I refer to approach 1) I would tend to create objects that perform their tasks by themself rather than other objects (DocumentManager) that do something with my DocumentObject.

(I hope this will not take the direction of a religious discussion about OOP ;).)

[/EDIT]


Old Version:

At first this seems to be a very basic question like "when to use static methods and when not" but this is something I'm confronted every now and then (and I have difficulties to describe what the real problem is; perhaps it's just to get reasons why (not) to use 1) or why (not) to use 2)).

(Although I'm using C#-Syntax this is not a C#-restricted problem)

In OOP there are two approaches (amongst others) of working with objects:

1) If I want my object to do something, I just tell him to do so:

myConcreteObject.DoSomething();

It's just like talking to an object.

2) Or if you're a fan of static methods:

ObjectClass.JustDoIt();

In some way I think static functions just "feel" better. So I tend to use static methods very often (to be independent from a concrete instance - independency is always good thing).

So, when designing a class I often have to decide if I take approach 1) or approach 2):

Imagine you have a class "Document" which should stand for a document that should be saved into a database:

A Document

  • consists of one or more image files from filesystem (these become the single document pages)
  • has something like a bibliography - fields the user can add information about the document to - which is saved to an extra file
  • and should have some operations like Copy(), AddPage(), RemovePage() etc.

Now I'm confrontated with several ways to create this class:

//----- 1) non static approach/talking to objects -----
Document newDocument = new Document();

// Copy document to x (another database, for example)
newDocument.Copy(toPath);

I like this: I tell the document to copy itself to database x and the object does so by itself. Nice.

//----- 2) static approach ----------------------------
Document.Copy(myDocumentObject, toPath);

Why not? Also nice, feels very handy...

So, which one to implement? Both? Or putting the static approach to a kind of helper class? Or choose approach 1) and stick with it to not weaken the interface of my Document-class?

When thinking about both approaches I come to the conclusion that (in theory) one could implement any function as a static function:

Class.Function(aConcreteClassObject, parameters);

but also non-static:

aConcreteObject.DoSomething(parameters);

To give a real-world example:

[EDIT(Added parameter fromPath "Sorry, I forgot")]

//----- 2) static approach ----------------------------
File.Copy(fromPath, toPath);    // .Net-Framework-like

[/EDIT]

but also:

//----- 1) non static approach ------------------------
ExampeFileClass fileObject = new ExampleFileClass();
fileObject.Copy(toPath);

or even (kind of OOP-Overkill):

//----- 1) non static approach, too -------------------
fileObject.ToPath = @"C:\Test\file.txt";     // property of fileObject
fileObject.Copy();                           // copy to toPath

So, why (not) to use 1) or why (not) to use 2)?

(I would not concentrate on the Document class example too much, since it's more a general question about good class design.)

like image 852
Inno Avatar asked Apr 28 '09 13:04

Inno


People also ask

How do you decide between natural birth and C-section?

A woman may choose to have a C-section if she has overwhelming anxiety about a vaginal birth, which may affect her experience of delivery. Women who have C-sections are less likely to suffer from urinary incontinence and pelvic organ prolapse compared with women who deliver vaginally.

Can I choose C-section?

Emergencies and complications can lead to a C-section, but you might be surprised to hear that some women choose to have a C-section without a medical reason. This is called an elective C-section.

When is C-section recommended?

A C-section might be recommended for women with certain health issues, such as a heart or brain condition. There's a blockage. A large fibroid blocking the birth canal, a pelvic fracture or a baby who has a condition that can cause the head to be unusually large (severe hydrocephalus) might be reasons for a C-section.

Is vaginal better than C-section?

Which is safer: vaginal birth or C-section? Vaginal birth is much safer than a C-section for most women and babies. Sometimes a C-section is the only safe option, like when the baby is positioned side-to-side in the belly (transverse lie) or the placenta is covering the cervix (placenta previa).


2 Answers

Here we go.

First off:

So I tend to use static methods very often (to be independent from a concrete instance - independency is always good thing).

Quite the contrary: when using static methods you're very dependent on the concrete instance.

As far as your Document is concerned, I'd go neither way. You've listed all responsibilities of Document class, which includes aggregation of data, saving itself to the database plus operations on pages and copying.

This is way to much. Per SRP, each "module" (here "module" used as a catch-all term) should have only one reason to change. Your Document has lots of responsibilities, hence it has a whole slew of reasons to change. This is no good.

With that in mind, I'd move all logic to other classes with strictly defined responsibilities. A more or less accepted criterion of what to move was introduced, I believe, by either Herb Sutter or Andrei Alexandrescu, an is as follows: all operations (think methods) that can be performed with an object through its public contract should be moved outside the object in question.


like image 83
Anton Gogolev Avatar answered Sep 30 '22 21:09

Anton Gogolev


You cannot use static methods to implement an interface, and you cannot override static methods. So using static methods means that you are simply not doing OOP.

Think about how you would implement the following functionality using only static methods?

interface IDocument 
{
   void Print(IDevice targetDevice);
}

IDocument instance;

instance = new PdfDocument();
instance.Print(printer);

instance = new WordDocument();
instance.Print(printer);
like image 44
Groo Avatar answered Sep 30 '22 23:09

Groo