Global vs function vs static class method

2019-02-13 20:56发布

Let's say you have a object that is unique, and it's used by all other classes and functions ...something like $application.

How would you access this object in your functions?

  1. using a global variable in each of you functions:

    global $application;
    $application->doStuff();
    
  2. creating a function, like application() that instantiates the object into a static variable and returns it; then use this function everywhere you need to access the object:

    application()->doStuff();
    
  3. create a singleton thing, like a static method inside the object class which returns the only instance, and use this method to access the object:

    Application::getInstance()->doStuff();
    
  4. KingCrunch & skwee: Pass the application object as argument to each function/class where is needed

    ...
    public function __construct(Application $app, ...){
      ....
    

If there are other options please post them. I'm wondering which of these options is the most efficient / considered "best practice".

3条回答
家丑人穷心不美
2楼-- · 2019-02-13 21:34

I'd pass it to all the needed methods. i.e.

function doFoo(Application $app) {
    $app->doStuff();
}

Both global and singleton considered bad and ties your code too much and this makes unit testing more difficult. There is one rule when you are allowed to use singleton, if you answer "yes" to the following statement:

Do I need to introduce global state to my application AND I must have a single instance of given object AND having more than one instance will cause error

If you answer yes to all the 3 parts then you can use singleton. In any other case just pass all the instances to all the method who needs them. If you have too much of them, consider using something like Context

class Context {
    public $application;
    public $logger;
    ....
}
========
$context = new Context();
$context->application = new Application();
$context->logger = new Logger(...);
doFoo($context);
========
function doFoo(Context $context) {
    $context->application->doStuff();
    $context->logger->logThings();
}

(you can use getters/setters if you need to protect the data or manipulate it or if you want to use lazy initiation etc).

Good luck!

查看更多
一纸荒年 Trace。
3楼-- · 2019-02-13 21:41

Or just give it to the ones, that are interested in it. All the suggestions you made are like global variables, even if you call it not that in 2 of 3 variants.

Before it comes to that: If you want to say "Thats not possible, because everything needs it", than maybe it does too much, can too much, and/or knows too much.

查看更多
神经病院院长
4楼-- · 2019-02-13 21:54

Singletons, God Classes, monolithic classes, etc. are all anti patterns, so I would suggest a fourth option: dependency injection. You can create an instance of application in your application via a factory (or perhaps even new if it has no dependencies, but this can end up complicating things later).

Then, any class that needs access to application can get it as a member, helpfully via the constructor. I'm sure that not every class needs access to application. Remember the Law of Demeter.

If you need some generic functionality like converting one static string to another, I suggest using php's global functions (as opposed to, for instance, a faux static class). I believe they were designed for that purpose.

查看更多
登录 后发表回答