Last active
August 22, 2016 21:52
-
-
Save ManInTheBox/59122ecd1615d12c6ec6d05e27d37ea9 to your computer and use it in GitHub Desktop.
Visitor pattern implementation in PHP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
interface EntityInterface | |
{ | |
/** | |
* @param VisitorInterface $visitor | |
*/ | |
public function accept(VisitorInterface $visitor); | |
} | |
interface VisitorInterface | |
{ | |
/** | |
* @param EntityInterface $entity | |
*/ | |
public function visit(EntityInterface $entity); | |
} | |
abstract class AbstractEmployee implements EntityInterface | |
{ | |
/** | |
* @var string | |
*/ | |
private $fullName; | |
/** | |
* @var float | |
*/ | |
private $salary; | |
/** | |
* @param string $fullName | |
*/ | |
public function __construct(string $fullName) | |
{ | |
$this->fullName = $fullName; | |
} | |
/** | |
* @return int | |
*/ | |
abstract public function getWorkingHours(); | |
/** | |
* @return float | |
*/ | |
abstract public function getHourlyRate(); | |
/** | |
* @return string | |
*/ | |
public function getFullName() : string | |
{ | |
return $this->fullName; | |
} | |
/** | |
* @return float | |
*/ | |
public function getSalary() : float | |
{ | |
return $this->salary; | |
} | |
/** | |
* @param float $salary | |
* | |
* @return Employee | |
*/ | |
public function setSalary(float $salary) : self | |
{ | |
$this->salary = $salary; | |
return $this; | |
} | |
/** | |
* @return string | |
*/ | |
public function __toString() : string | |
{ | |
return sprintf('%s earns $%f', $this->getFullName(), $this->getSalary()); | |
} | |
} | |
class Developer extends AbstractEmployee | |
{ | |
/** | |
* {@inheritdoc} | |
*/ | |
public function getHourlyRate() : float | |
{ | |
return 34.56; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function getWorkingHours() : int | |
{ | |
return 170; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function accept(VisitorInterface $visitor) | |
{ | |
$visitor->visit($this); | |
} | |
} | |
class Boss extends AbstractEmployee | |
{ | |
/** | |
* {@inheritdoc} | |
*/ | |
public function getWorkingHours() : int | |
{ | |
return 80; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function getHourlyRate() : float | |
{ | |
return 88.55; | |
} | |
/** | |
* @return float | |
*/ | |
public function getBonus() : float | |
{ | |
return 325; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function accept(VisitorInterface $visitor) | |
{ | |
$visitor->visit($this); | |
} | |
} | |
class DeveloperSalaryVisitor implements VisitorInterface | |
{ | |
/** | |
* {@inheritdoc} | |
*/ | |
public function visit(EntityInterface $developer) | |
{ | |
$salary = $developer->getWorkingHours() * $developer->getHourlyRate(); | |
$developer->setSalary($salary); | |
} | |
} | |
class BossSalaryVisitor implements VisitorInterface | |
{ | |
/** | |
* {@inheritdoc} | |
*/ | |
public function visit(EntityInterface $boss) | |
{ | |
$salary = ($boss->getWorkingHours() * $boss->getHourlyRate()) + $boss->getBonus(); | |
$boss->setSalary($salary); | |
} | |
} | |
$developer = new Developer('Pera Zdera'); | |
$boss = new Boss('Milojko Pantic'); | |
$developer->accept(new DeveloperSalaryVisitor()); | |
$boss->accept(new BossSalaryVisitor()); | |
echo sprintf('%s', $developer); | |
echo "\n"; | |
echo sprintf('%s', $boss); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment