Question

So I'm developing an application which is using an IoC container. Now I need some helper methods for array manipulation like set, get, etc. I see two possible ways to go:

  1. Using a class with static methods.
  2. Using a class with non-static methods registered in the IoC container.

When using method 1, it will look something like this:

$arr = array(); // Defining $arr
Arr::set($arr, 'a', 'b'); // Sets 'a' => 'b' in $arr
echo Arr::get($arr, 'a'); // Outputs 'b'

And using method 2, I will first register a new Arr class in the IoC container and than using it would look something like this:

$arr = array(); // Defining $arr
$app['arr']->set($arr, 'a', 'b'); // Sets 'a' => 'b' in $arr
echo $app['arr']->get($arr, 'a'); // Outputs 'b'

According to my benchmarks, method 1 is almost twice as fast as method 2. So in terms of performance method 1 is the way to go (I think). But, static methods are generally considered bad practice. So in terms of best practices, I should use method 2 to avoid static methods.

My question is if I should use the IoC container for helper methods or just use the static methods.

Was it helpful?

Solution

There's nothing wrong with static methods. That's one of those things people say to sound smart and shocking, but the reality is much more subtle and can't be explained in the title of a blog post!

So why not static methods? Static methods can't be part of a contract. That means you can't implement more than one version and you can't swap those versions seamlessly behind the contract. Thing is, that might not matter. Would you ever need more than one version of a math min function? I hope not.

Be careful though, it's not always simple to decide if you need more than one version of a function. Take file manipulation. You should only ever need one version of those functions, right? Well, er, no. The problem shows up when you want to test your code. Say you have a little chunk of code you want to test and it has a dependency on a file function. Testing that code gets tricky if your system isn't set up exactly like the developer who originally wrote the test. Maybe you're missing a file or your file is slightly different or your file permissions are different or... It gets complicated pretty quick. Soon, you realize you're testing that stupid file function more than you're testing the function that depends on it. That's no good.

The solution is to provide a second version of the file function that's perfectly predictable. If it always behaves the same, you're free to test the code that depends on it without worrying that it might zig when you expect it to zag. Problem solved; but remember, you can't have two versions of a static method.

So back to your question. I'll say this:

  1. Don't worry about performance until you've confirmed it's a problem. Beautiful, maintainable code is more important than performance at this point in the game.
  2. Array manipulation is a perfect candidate for static methods. You'll never need more than one version because there should only be one way to do the tasks you're defining and there's no test-ruining dependencies on the file system, database, network, etc...

OTHER TIPS

Either way works. Personally, I have written similar classes for things like array manipulation and math functions. I used static methods because those things are true functions and do not operate on any encapsulated data, so it seemed to make more conceptual sense. Plus, I didn't want to have to instantiate an object whenever I called one of those methods.

Some people say to avoid static methods. It is true that they can have downside. My personal opinion is that static methods are fine for things like utilities classes like what you seem to be writing.

Licensed under: CC-BY-SA with attribution
scroll top