3

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?

ChaosPandion
  • 77,506
  • 18
  • 119
  • 157
Tyler Carter
  • 60,743
  • 20
  • 130
  • 150
  • Here's a pattern I've seen: `class Frob { void tweak() {...} static void tweakIfNotNull(Frob f) { if (f != null) f.tweak(); } }` This is mainly convenient when the method is something that needs to be recursively applied to every node in a big tree of data. Like *serialize()* or *dispose()*. Each class uses the ifNotNull version on its children. – Jason Orendorff Jan 30 '10 at 00:48
  • Another pattern I've seen is where the static methods are basically a facade for the rest of the class. http://en.wikipedia.org/wiki/Facade_pattern – Jason Orendorff Jan 30 '10 at 00:48
  • The notion of "static" isn't language-agnostic, it's quite to specific to a small number of them, and even within that set of languages, the best practice varies. – skaffman Jan 30 '10 at 10:55

10 Answers10

7

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

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

private:
  Foo();
};
i_am_jorf
  • 53,608
  • 15
  • 131
  • 222
  • 2
    +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 Jan 30 '10 at 00:04
  • 1
    You could use a factory in this case – Samuel Carrijo Jan 30 '10 at 00:07
  • 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 Jan 30 '10 at 11:14
5

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
  • 57,174
  • 8
  • 131
  • 162
3

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

Messa
  • 24,321
  • 6
  • 68
  • 92
2
  • 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
  • 588,226
  • 146
  • 1,060
  • 1,140
1

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
  • 77,506
  • 18
  • 119
  • 157
1

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()
Eugene Yokota
  • 94,654
  • 45
  • 215
  • 319
0

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
  • 776,304
  • 153
  • 1,341
  • 1,358
0

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;
}
0

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
  • 562,542
  • 136
  • 1,062
  • 1,124
0

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
  • 11,477
  • 34
  • 49