views:

220

answers:

10

I'm trying to figure out when it would be appropriate for a class to have both static and non-static functions. AKA:

$obj = new ClassA;
$obj->doOOPStuff();

$something = ClassA::doStaticStuff();

Note: This example is done in PHP, however the question is language agnostic .

It seems that if you have a class that is meant to be instantiated, any functions that can be called statically, most likely belong in another class.

Is there any viable cases where I would have a class that used static AND non-static members?

+7  A: 

One example: when Creation has to happen in a specific way.

class Foo {
public:
  static Foo* Create(...params...);

private:
  Foo();
};
jeffamaphone
+1: That's a usage pattern I've used several times. I find it clearer to make complex creation procedures as their own methods rather than overload the constructor (e.g. `c = C::fromXml(xmldoc)` rather than `c = new C(xmldoc)`).
Max Shawabkeh
You could use a factory in this case
Samuel Carrijo
This pattern is called factory method. I found it heavily used in Objective-C frameworks, although factory method should only be used for convenience constructors IMHO.
Johannes Rudolph
A: 

Static class members are most useful where everything must either be in an object or be in a global scope; they are less useful in a language such as Python that supports module-level scopes.

Ignacio Vazquez-Abrams
+1  A: 

Imagine your constructor has two overloads that both are strings:

public class XmlDocument
{
    public static XmlDocument CreateFromFile(string filePath);
    public static XmlDocument CreateFromXml(string xml);
}
ChaosPandion
This doesn't require static methods. You could create a class for each, or include another parameter, for instance. It's valid, though.
Samuel Carrijo
Yeah, technically you could detect if the string passed in was a valid file path, and if so load from file.
Chacha102
Why would you want two classes? Also would you really want a constructor like this? `public XmlDocument(string filePath, string xml)`
ChaosPandion
@Chacha - Does this look like JavaScript to you? :)
ChaosPandion
@Chaos What? Only Javascript gets to have the fun of auto-detection arguments? :)
Chacha102
@Chacha - Well mainly dynamic languages do such things.
ChaosPandion
Could be a public XmlDocument(enum fileType, string content), or maybe public XmlDocument(FilePath filePath). As I said, your approach is also valid, I was just showing alternatives.
Samuel Carrijo
+3  A: 

If the functionality provided by static methods is relevant to that class and its objects, why not. It is pretty common.

Messa
+1  A: 

The static function can provide meaningful name to the constructor.

$dialog = DialogFoo::createOpenDialog();
$dialog = DialogFoo::createDocumentOpenDialog();
$dialog = DialogFoo::createImageOpenDialog();

It could also be used to enforce Singleton pattern.

$dialog = DialogFoo::getInstance()
eed3si9n
+5  A: 

Consider String class in .NET. It contains a non-static Split method which breaks some instance into a string[] and a static Join method, which takes a string[] and transform it into a string again.

A static method is applicable when you don't need to keep any state. So Math.Sin() just depends on its parameters and, given same parameters, output will always be the same. A non-static method can have different behavior is called multiple times, as it can keep a internal state.

Rubens Farias
+2  A: 
  • Static method are most often factory methods

    public class MyClass {    
        public static MyClass createMyClass(int a, double b) {..}
        public static MyClass createSubclassOfMyClass(int c, boolean cond) {..}
        public int calculateThis();
        public double calculateThat();
    }
    
  • Another use is to access some property that is logically bound that that class, but not separately to instances. For example - a cache:

(Note - of course synchronization should be taken into account in this example)

public class MyClass {
    public static final Cache cache = new Cache();
    public static void putInCacheIfNeeded(Object obj) {..}
    public static void replaceInCache(Object obj) {..}

    public void doSomethingCacheDependend(Object obj) {
        if (something) {
             MyClass.putInCacheIfNeeded(obj);
        } else {
             MyClass.replaceInCache(obj);
        }
    }
}

(Java language for the examples)

Bozho
+1, perfect answer if you'd also add private, stateless utility functions.
Johannes Rudolph
A: 

I use static methods to instantiate new objects when I dont want the to give access to the constructor. I ensure that any necessary preconditions are carried out on the class before creating and object. In this example I have a counter to return how many objects are created, if I have 10 objects I prevent any more from being instantiated.

class foo {
private:
static int count;
foo() {}

public:
static foo bar() {
count++;
if (count<=10){
return new foo;
} else {
return null;
}
A: 

Let's assume a class has instance methods, here are some good use case for having static methods too:

For static utility methods

Such methods apply to any instance, for example String.format(String, Object...) in Java.

Use them when you don't want to create a specific instance for the job.

For static factory methods

Factory methods are methods that simply instantiate objects like the getInstance() and valueOf() methods in the Java API. getInstance() is the conventional instantiation method in singletons while valueOf() are often type-conversion methods, like in String.valueOf(int).

Use them to improve performance via object-caching, in interface-based frameworks (like the Collections Framework in Java) where you may want to return a subtype, to implement singletons (cough).

Pascal Thivent
A: 

In general, static functions produce functionality highly related to class itself. It may be some helper functions, factory methods etc. In this case all functionality contains in one place, it correspond to DRY principle, increases cohesion and reduces coupling.

Sergey Teplyakov