Skip to content

Instantly share code, notes, and snippets.

@ManInTheBox
Last active August 22, 2016 21:52
Show Gist options
  • Save ManInTheBox/59122ecd1615d12c6ec6d05e27d37ea9 to your computer and use it in GitHub Desktop.
Save ManInTheBox/59122ecd1615d12c6ec6d05e27d37ea9 to your computer and use it in GitHub Desktop.
Visitor pattern implementation in PHP
<?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