A class should have only one responsibility and shouldn't do or know more than what it meant to. A class that knows too much or does too much is called "God object".


# VIOLATION
class User
{
private $firstname;
private $lastname;

public function setFirstname(string $firstname)
{
$this->firstname = $firstname;
}

public function setLastname(string $lastname)
{
$this->lastname = $lastname;
}

public function output(): string
{
return sprintf('Hello:%s %s', $this->firstname, $this->lastname);
}
}

$user = new User();
$user->setFirstname('Robert');
$user->setLastname('DeNiro');
echo $user->output();

As you can see above, User class seems to be responsible for outputting as well as setting and getting user information which is what causes violation.


# REFACTORED
interface UserInterface
{
public function setFirstname(string $firstname);
public function getFirstname(): string;
public function setLastname(string $lastname);
public function getLastname(): string;
}

class User implements UserInterface
{
private $firstname;
private $lastname;

public function setFirstname(string $firstname)
{
$this->firstname = $firstname;
}

public function getFirstname(): string
{
return $this->firstname;
}

public function setLastname(string $lastname)
{
$this->lastname = $lastname;
}

public function getLastname(): string
{
return $this->lastname;
}
}

class UserOutputer
{
private $user;

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

public function plain(): string
{
return sprintf('Hello:%s %s', $this->user->getFirstname(), $this->user->getLastname());
}
}

$user = new User();
$user->setFirstname('Robert');
$user->setLastname('DeNiro');

$userOutputter = new UserOutputer($user);
echo $userOutputter->plain();

As you can see above, we have introduced a new class called UserOutputer and shipped outputting responsibility from User class to it. We now have:



We can even easily add JSON and XML formats as output options to UserOutputer class without even touching User class.