Skip to content

Instantly share code, notes, and snippets.

@Kcko
Created April 10, 2020 19:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Kcko/39e9f38201e87a0e20a63714a788f7bc to your computer and use it in GitHub Desktop.
Save Kcko/39e9f38201e87a0e20a63714a788f7bc to your computer and use it in GitHub Desktop.
<?php
// Visitor
/*
Definice
--------
Návrhový vzor Visitor vám umožní přidat nové operace do struktury objektů bez
změny prvků této struktury. Operace, které se mají v této struktuře provést, jsou
zapouzdřené do nové třídy.
Pro vytvoření a použití návštěvníka i v jiných situacích jsou nutné následující
kroky:
1. Analyzovat, jaké typy prvků, které chcete rozšířit o nové funkce, se nacházejí
ve struktuře objektů.
2. Definovat rozhraní pro objekt návštěvníka s deklaracemi metod visit*()
pro každý typ prvku.
3. Do každé třídy, která se používá ve struktuře objektů, přidat metodu
acceptVisitor(), která přijme objekt implementující rozhraní z bodu 2.
V této metodě zavolat příslušnou metodu visit*() objektu návštěvníka
a předat jí aktuální objekt.
4. Projít všechny objekty, na které odkazuje aktuální objekt (poduzly), a jejich
metodě acceptVisitor()předat objekt návštěvníka.
*/
interface Publication
{
// ... stávající metody rozhraní
public function acceptVisitor(Visitor $visitor);
}
interface Visitor
{
public function visitLibrary(Library $library);
public function visitRentalAction(RentalAction $rentalAction);
public function visitPublication(Publication $publication);
public function visitMember(Member $member);
}
class Library
{
// ... atributy a metody třídy
public function acceptVisitor(Visitor $visitor)
{
$visitor->visitLibrary($this);
foreach ($this->rentalActions as $rentalAction)
{
$rentalAction->acceptVisitor($visitor);
}
}
}
class RentalAction
{
// ... atributy a metody třídy
public function acceptVisitor(Visitor $visitor)
{
$visitor->visitRentalAction($this);
$this->publication->acceptVisitor($visitor);
$this->member->acceptVisitor($visitor);
}
}
class Member
{
// ... atributy a metody třídy
public function acceptVisitor(Visitor $visitor)
{
$visitor->visitMember($this);
}
}
class VisitorEcho implements Visitor
{
public function visitLibrary(Library $library)
{
print "Knihovna\n";
}
public function visitRentalAction(RentalAction $rentalAction)
{
printf(" + Publikace vypůjčená od %s", $rentalAction->getRentDate());
if ($rentalAction->isReturned()) {
printf(" do %s\n", $rentalAction->getReturnDate());
} else {
print " - dosud nevrácena\n";
}
}
public function visitPublication(Publication $publication)
{
printf(" - Kategorie: %s\n", $publication->getCategory());
printf(" - Počet stran: %d\n", $publication->getPageCount());
}
public function visitMember(Member $member)
{
printf(" - Čtenář: %s\n", $member->getName());
}
}
$visitor = new VisitorEcho();
$library->acceptVisitor($visitor);
<?php
class VisitorXMLExport implements Visitor
{
protected $doc;
protected $root;
protected $currentAction = null;
public function __construct()
{
$this->doc = new \DOMDocument('1.0', 'UTF-8');
$this->doc->formatOutput = true;
}
public function visitLibrary(Library $library)
{
$this->root = $this->doc->createElement('library');
$this->doc->appendChild($this->root);
}
public function visitRentalAction(RentalAction $rentalAction)
{
$this->currentAction = $this->doc->createElement('rentalAction');
$this->root->appendChild($this->currentAction);
$this->currentAction->setAttribute(
'rentDate',
$rentalAction->getRentDate()
);
if ($rentalAction->isReturned()) {
$this->currentAction->setAttribute(
'returnDate',
$rentalAction->getReturnDate()
);
}
}
public function visitPublication(Publication $publication)
{
$tag = $this->doc->createElement('publication');
$tag->setAttribute('category', $publication->getCategory());
$tag->setAttribute('pageCount', $publication->getPageCount());
$this->currentAction->appendChild($tag);
}
public function visitMember(Member $member)
{
$tag = $this->doc->createElement('member');
$tag->setAttribute('id', $member->getId());
$tag->setAttribute('name', $member->getName());
$this->currentAction->appendChild($tag);
}
public function asXML()
{
return $this->doc->saveXML();
}
}
$visitor = new VisitorXMLExport();
$library->acceptVisitor($visitor);
print $visitor->asXML()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment