views:

73

answers:

2

Are there any reasons I should not create a final class with static methods to avoid that some internal functions are called?

final class ModuleGlobalFunctions {
  static public function generateWord {
    $result = '';

    while (strlen($result) < 12) {
      $result = self::generateSyllable();
    }

    return $result
  }

  static private function generateSyllable() {
    // Generates a random syllable.
    // …
  }
}

$word = Test::generateWord();

// It raises an error.
$syllable = Test::generateSyllable();
+1  A: 

Creating a class to shield off private functions is a good idea. This way, a public method in the class can call a private method, without making the private method callable from outside the class.

Making a class final is also a good idea, as this indicates that the class has not been designed with overloading in mind, and makes the class simpler.

Making the class static is a bad idea, because it tightly couples the caller to the class. If you call Test::generateWord(), this will always use the Test class. However, if you use $test->generateWord(), you can pass in another class, which creates other words. This makes it easier to change the software and easier to unit test it.

Sjoerd
I am not sure I understand the last part. Do you mean it would be better if I would not define the methods as static (even if they are not going to use any class properties)?
kiamlaluno
+3  A: 

Well, personally, I would recommend using classes to group similar logic. So in your case (the example you provided), it's a good idea.

As for final, it's a toss up. I prefer to use abstract to prevent instantiation (since PHP doesn't support static classes). If you do use final, I would suggest adding a private constructor to prevent instantiation: private function __construct() {}...

Personally, I like the concept of keeping it static. The reason is three fold. First, it's easier on memory (since there are no instances to keep track of). Second, it's faster (A static method call is faster than an instance method call). Third, and more importantly, it makes sense. Instances have a state (that's why they are instances). Does your class need a state? If so, then use an instance. If not, that's exactly what static classes are meant for...

As for passing an instance as Sjoerd mentions, you can do that with static classes (and actually be less tightly coupled than with instances). Here's the reason. Unless you require (and check for) an interface or inheritance, you have no idea if the object actually implements the method generateWord(). But, if you pass in a callback, it doesn't matter how the method is accessed (or its underlying construction), all that matters is that it has the same (or similar) syntax (with respect to parameters and return values). Now, interfaces are a better solution to this (since it enforces the interface), but they require pretty deep understanding of OOP to get the design right. In a pinch, a callback will work quite fine for that case...

ircmaxell
The faster argument is very weak; the difference is very small: http://codepad.viper-7.com/dhL1dK
Artefacto
The memory argument is weak for the same reason.
Sjoerd