<?php
include "1.php";
/*
Návrhový vzor Bridge odděluje rozhraní třídy od její vlastní implementace a umožňuje
provádět jejich změnu nezávisle na sobě.
*/
/*
Definice
--------
Návrhový vzor Bridge odděluje rozhraní třídy od její vlastní implementace a umožňuje
provádět jejich změnu nezávisle na sobě.
Pro dosažení tohoto cíle je nutné provést následující kroky:
1. Definovat rozhraní nezbytné pro jednotlivé implementace.
2. Vytvořit minimálně dvě třídy implementující rozhraní z bodu 1.
3. Vytvořit způsob, jak abstrakci předat konkrétní implementaci.
4. V abstrakci využívat služby implementace z bodu 2 přes rozhraní definované
v bodě 1.
Shrnutí
-------
Návrhový vzor Bridge odděluje abstrakci od její konkrétní implementace a zamezuje
tak zbytečnému nárůstu počtu tříd při předávání implementací. Tento
návrhový vzor řeší podobný problém jako návrhový vzor Adapter, představený
v předchozí kapitole. Rozdíl mezi těmito dvěma vzory je především v tom, že
vzor Bridge se používá již při návrhu aplikace, zatímco vzor Adapter řeší problém,
jak zabezpečit komunikaci již hotových tříd.
*/
interface Storage
{
public function insertPublication($id, Publication $p);
public function fetchPublications();
}
class StorageArray implements Storage
{
protected $publications;
public function insertPublication($id, Publication $p)
{
$this->publications[$id] = $p;
}
public function fetchPublications()
{
return $this->publications;
}
}
// Upravena trida library oproti 1 dilu
abstract class AbstractLibrary
{
protected $rentalActions = array();
protected $debugger;
protected $storage;
public function __construct(Debugger $debugger, Storage $storage)
{
$this->debugger = $debugger;
$this->storage = $storage;
}
protected function debug($message)
{
$this->debugger->debug($message);
}
public function rentPublication(Publication $p, Member $m)
{
$publicationId = array_search($p, $this->getPublications());
if (false === $publicationId) {
throw new UnknownPublicationException();
}
if (!$this->isPublicationAvailable($p)) {
throw new PublicationNotAvailableException();
}
$rentalAction = new RentalAction($p, $m);
$this->rentalActions[] = $rentalAction;
$this->debug(
$m->getName() . ' si vypůjčil publikaci: ' . $p->getCategory()
);
return $rentalAction;
}
public function returnPublication(Publication $p)
{
foreach ($this->rentalActions as $rentalAction)
{
if ($rentalAction->getPublication() !== $p) {
continue;
}
if ($rentalAction->isReturned()) {
continue;
}
$rentalAction->markPublicationReturned();
$this->debug(
$rentalAction->getMember()->getName() .
' vrátil publikaci: ' .
$p->getCategory()
);
return true;
}
return false;
}
public function isPublicationAvailable(Publication $p)
{
foreach ($this->rentalActions as $rentalAction)
{
if ($rentalAction->getPublication() !== $p) {
continue;
}
if ($rentalAction->isReturned()) {
continue;
}
return false;
}
return true;
}
public function generateId()
{
$publications = $this->getPublications();
return 'PUBLICATION-' . count($publications);
}
public function getPublications()
{
return $this->storage->fetchPublications();
}
abstract public function addToLibrary($id, Publication $p);
}
class Library extends AbstractLibrary
{
public function addToLibrary($id, Publication $p)
{
$this->storage->insertPublication($id, $p);
$this->debug('Nová publikace v knihovně: ' . $p->getCategory());
}
}
// Storages
class StorageDatabase implements Storage
{
protected $db;
public function __construct($filename)
{
$this->db = new \SQLiteDatabase($filename, 0666);
$this->initialiseDatabase();
}
public function insertPublication($id, Publication $p)
{
// INSERT TO DB
}
public function fetchPublications()
{
// SELECT FROM DB && FETCH to $publications (array or ...)
return $publications
}
protected function initialiseDatabase()
{
// connection to db
}
}
class StorageArray implements Storage
{
protected $publications;
public function insertPublication($id, Publication $p)
{
$this->publications[$id] = $p;
}
public function fetchPublications()
{
return $this->publications;
}
}
// USAGE
$publication1 = new Book('PC', 450);
$publication2 = new Book('MEDICINA', 50);
$storage = new StorageDatabase('library.sqlite');
$debugger = DebuggerEcho::getInstance();
$library = new Library($debugger, $storage);
$library->addToLibrary($library->generateId(), $publication1);
$library->addToLibrary($library->generateId(), $publication2);
$publications = $library->getPublications();
print_r($publications);