简体   繁体   中英

Which approach is better when passing settings to an object?

I want to set initial values of fields in an object, using $config. Which approach is better in terms of cleaner and more maintainable code? Also, I would like to add that object will be initialized in a factory and not directly by client.

1. I pass $config to the object

<?php
class UserGreeting {
  private $config;
  public function __construct($config){
      $this->config=$config;
  }

  public function greetings(){
    echo 'Hello, '.$this->config->get('username');
  }
}
?>

Pros:

  • Easy to pass multiple parameters

Cons:

  • The class is coupled with $config ( is it?). What I mean is that apart from particular $config interface and parameters naming conventions, I can't just plug this class into another program without introducing $config
  • Client code doesn't have to know which parameters are used by the
    object, but that is more general thought

2. I set fields manually outside the object

<?php
class UserGreetingFactory{
   public function __construct($config){
     $this->config=$config;
   }
   public function getUserGreeting(){
     $userGreeting=new UserGreeting();
     $userGreeting->setUserName='John Doe';
     return $userGreeing;
   }
} 

class UserGreeting {
   private userName;
   public function setUserName($userName){
     $this->userName=$userName;
   }
   public function greetings(){
     echo "Hello, {$this->userName}";
   }
  }
?>

Pros:

  • The class doesn't care where his parameters are coming from

  • Can reuse easily

  • Easier to test(is it?). I mean that I don't have to deal with setting up $config

Cons:

  • Factory\\Builder has to know which parameers to pass

  • Lots of extra code for setters and passing parameters

First solution with ctor injection. But instead of a special config i would just pass the actual objects. In your case an User object.

<?php
class UserGreeting
{
    private $user;

    public function __construct(User $user)
    {
        $this->user = $user;
    }

    public function greet()
    {
        printf('Hello, %s!',  $this->user->getName());
    }
}

Considering your idea's, I'd stick to a single variable. If you want to pass the variables per-method you'll have a lot of excessive code.

From an OOP point of view, you shouldn't put it in a single variable. An object has properties. An username is in fact a property so you should use it as property. That means that in PHP classes you'd need to make it a public variable and set the variables when you create the object.

The first way is better because of dependency injection. This code will be easier to test and to maintain. The third way is to use Visitor pattern to inject dependencies.

You could use a static class with static methods. In effect they are like CONSTS, but you can enforce all kinds of rules within the static config class - that they conform to an interface for example.

Config::getUserName();

That way if you are going to be faced with a family of config objects, you can be assured they all have at least an entry for each expected value - otherwise a warning is chucked.

Might depend on your situation of course, and I expect there are many situations where you would not want to do this - but I will offer it up all the same.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM