Should a class ever have static and non-static mem

2019-04-11 17:31发布

问题:

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?

回答1:

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

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

private:
  Foo();
};


回答2:

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.



回答3:

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



回答4:

  • 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)



回答5:

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


回答6:

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()


回答7:

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.



回答8:

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


回答9:

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).



回答10:

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.