Last active
April 10, 2020 15:03
-
-
Save Kcko/7ca1487906fd7ad0e3f6ad37de2be43a to your computer and use it in GitHub Desktop.
This file contains 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 | |
/* | |
Definice | |
--------- | |
Návrhový vzor Observer definuje závislost 1:n mezi subjektem a libovolným počtem | |
pozorovatelů. Při změně stavu subjektu jsou o této skutečnosti automaticky informovány | |
všechny pozorovatele. | |
Pro implementaci tohoto návrhového vzoru jsou nutné následující kroky: | |
1. Definovat rozhraní (Observer) pro pozorovatele, které vyžaduje jednu | |
metodu, prostřednictvím níž jsou pozorovatelé informovaní o změně stavu | |
objektu. | |
2. Definovat rozhraní (Observable) pro pozorované objekty. Toto rozhraní | |
musí vyžadovat metody na přidání a odstranění pozorovatelů a také metodu | |
notify(), pomocí níž jsou pozorovatele informovány o změně stavu | |
pozorovaného objektu. rozdílem. Pozorovatel žádné hodnoty týkající se pozorovaného objektu – je bezstavový. Tento pozorovatel | |
tedy může současně pozorovat více objektů. Pozorovatel naopak uchovává informaci, kdy má nastat další pravidelná kontrola – uchovává | |
určitý stav. Protože se tato hodnota může u různých tiskáren lišit, lze jej použít | |
jen pro pozorování jednoho objektu. Pro každý další objekt je nutné vytvořit nový objekt pozorovatele. | |
3. V pozorovaném objektu implementovat rozhraní Observable. | |
4. Do metod, které mění stav objektu, vložit volání metody notify(). | |
5. Implementovat konkrétní pozorovatele. | |
*/ | |
interface Printer | |
{ | |
public function turnOn(); | |
public function turnOff(); | |
public function printPublication(Publication $p, $count = 1); | |
public function getType(); | |
public function getPageCounter(); | |
} | |
interface Observable | |
{ | |
public function attach(Observer $observer); | |
public function detach(Observer $observer); | |
public function notify(); | |
} | |
interface Observer | |
{ | |
public function update(Observable $observable); | |
} | |
class LaserPrinter implements Printer, Observable | |
{ | |
protected $turnedOn = false; | |
protected $type = null; | |
protected $pageCounter = 0; | |
protected $observers = array(); | |
function __construct($type) | |
{ | |
$this->type = $type; | |
} | |
public function turnOn() | |
{ | |
$this->turnedOn = true; | |
} | |
public function turnOff() | |
{ | |
$this->turnedOff = false; | |
} | |
public function getType() | |
{ | |
return $this->type; | |
} | |
public function printPublication(Publication $p, $count = 1) | |
{ | |
if (true !== $this->turnedOn) { | |
return false; | |
} | |
$pageCount = $p->getPageCount(); | |
$this->pageCounter += $pageCount * $count; | |
// 2 OBSERVER | |
$this->notify(); | |
return true; | |
} | |
public function getPageCounter() | |
{ | |
return $this->pageCounter; | |
} | |
// OBSERVE THINGS | |
public function attach(Observer $observer) | |
{ | |
$this->observers[] = $observer; | |
} | |
public function detach(Observer $observer) | |
{ | |
$this->observers = array_diff($this->observers, array($observer)); | |
} | |
public function notify() | |
{ | |
foreach($this->observers as $observer) | |
{ | |
$observer->update($this); | |
} | |
} | |
} | |
class ObserverInitialCheck implements Observer | |
{ | |
protected $checkPageCounter; | |
public function __construct($pageCounter = 10000) | |
{ | |
$this->checkPageCounter = $pageCounter; | |
} | |
public function update(Observable $observable) | |
{ | |
if (!$observable instanceof Printer) { | |
return; | |
} | |
if ($observable->getPageCounter() >= $this->checkPageCounter) { | |
printf( | |
"Nutná prvotní kontrola po %d vytištěných stranách.\n", | |
$this->checkPageCounter | |
); | |
$observable->detach($this); | |
} | |
} | |
} | |
$book = new Book('PC', 580); | |
$printer = new LaserPrinter('Printer 1'); | |
$initialCheck = new ObserverInitialCheck(10000); | |
$printer->attach($initialCheck); | |
$printer->turnOn(); | |
$printer->printPublication($book, 10); | |
printf("Počet vytištěných stran: %d\n", | |
$printer->getPageCounter()); | |
$printer->printPublication($book, 10); | |
printf("Počet vytištěných stran: %d\n", | |
$printer->getPageCounter()); | |
$printer->turnOff(); | |
/* | |
Počet vytištěných stran: 5800 | |
Nutná prvotní kontrola po 10000 vytištěných stranách. | |
Počet vytištěných stran: 11600 | |
*/ | |
class ObserverRegularCheck implements Observer | |
{ | |
protected $nextCheck = null; | |
protected $interval; | |
public function __construct($start, $interval) | |
{ | |
$this->nextCheck = $start; | |
$this->interval = $interval; | |
} | |
public function update(Observable $observable) | |
{ | |
if (!$observable instanceof Printer) { | |
return; | |
} | |
if ($observable->getPageCounter() >= $this->nextCheck) | |
{ | |
printf( | |
"Pravidelná kontrola po %d vytištěných stranách.\n", | |
$this->nextCheck | |
); | |
$this->nextCheck += $this->interval; | |
} | |
} | |
} | |
$book = new Book('PC', 580); | |
$printer = new LaserPrinter('Printer 1'); | |
$initialCheck = new ObserverInitialCheck(10000); | |
$regularCheck = new ObserverRegularCheck(40000, 30000); | |
$printer->attach($initialCheck); | |
$printer->attach($regularCheck); | |
$printer->turnOn(); | |
$printer->printPublication($book, 20); | |
printf("Počet vytištěných stran: %d\n", | |
$printer->getPageCounter()); | |
$printer->printPublication($book, 60); | |
printf("Počet vytištěných stran: %d\n", | |
$printer->getPageCounter()); | |
$printer->printPublication($book, 50); | |
printf("Počet vytištěných stran: %d\n", | |
$printer->getPageCounter()); | |
$printer->turnOff(); | |
/* | |
Nutná prvotní kontrola po 10000 vytištěných stranách. | |
Počet vytištěných stran: 11600 | |
Pravidelná kontrola po 40000 vytištěných stranách. | |
Počet vytištěných stran: 46400 | |
Pravidelná kontrola po 70000 vytištěných stranách. | |
Počet vytištěných stran: 75400 | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment