This is more a matter of semantics than a best practice for each of them.
In your example, the logic of your business can determine that the animal always needs a name. Therefore, it makes sense to build an object with a name. If you do not want to resolve the name of the animal that needs to be changed, then you are not writing a setter.
i.e.
class Animal { private $name; public function __construct($name) { $this->name = $name; } public function getName() { return $this->name; } }
You may have other properties that the animal should not have, for example, the owner that you only write a getter / setter for ie
class Animal { private $name; private $owner; public function __construct($name) { $this->name = $name; } public function getName() { return $this->name; } public function setOwner($owner) { $this->owner = $owner } }
But if you find that you always create an animal with the owner at the same time, you may want to put this in the counterparty’s signature for convenience
class Animal { private $name; private $owner; public function __construct($name, $owner = null) { $this->name = $name; $this->owner = $owner; } public function getName() { return $this->name; } public function setOwner(Owner $owner) { $this->owner = $owner } public function getOwner() { return $this->owner; } }
If the owner is another class in your application, you can enter a hint that your constructor requires an owner of a certain type (class). All this is used to make it easier for you or another developer to understand some of the requirements / logic of your code, as well as to potentially catch an error here or there.
class Owner { private $name; public function __construct($name) { $this->name = $name; } } class Animal { private $name; private $owner; public function __construct($name, Owner $owner = null) { $this->name = $name; $this->owner = $owner; } public function getName() { return $this->name; } public function setOwner(Owner $owner) { $this->owner = $owner } public function getOwner() { return $this->owner; } }
source share