<?php
/*
Návrhový vzor Facade poskytuje zjednodušené rozhraní pro sérii rozhraní. Nabízí
rozhraní, které zjednodušuje používání základního systému.
Pro implementaci návrhového vzoru Facade jsou nutné následující kroky:
1. Identifikovat třídy a objekty systému, které mají být schované za fasádou.
2. Definovat operace, které má fasáda umožnit.
3. Implementovat třídy fasády a vytvořit metody, pomocí nichž je fasáda
schopná přistupovat ke schovaným komponentám.
4. Ve třídě fasády implementovat metody, které umožní zjednodušený přístup
k jednotlivým komponentám systému za účelem provedení různých operací.
Na první pohled se návrhový vzor Facade podobá vzoru Adapter. Avšak fasáda
se na rozdíl od adaptéru nevyužívá k přizpůsobení jednoho rozhraní druhému.
Fasáda zjednodušuje stávající rozhraní, redukuje počet tříd, které musí klient
používat, a zjednodušuje použitelnost určitého subsystému.
Fasáda rovněž prosazuje něco,
*/
/*
Příklad v knize je takový nic moc.
*/
class FacadePurchase
{
protected $library = null;
protected $publishers = array();
public function __construct(Library $library)
{
$this->library = $library;
}
public function addPublisher($id, AbstractPublisher $publisher)
{
$this->publishers[$id] = $publisher;
}
public function purchase($publisher, $pageCount)
{
if (!isset($this->publishers[$publisher])) {
throw new UnknownPublisherException('Neznámý vydavatel');
}
$publication = $this->publishers[$publisher]->sellPublication(
$pageCount
);
$id = IdGenerator::getInstance()->generateId();
$this->library->addToLibrary($id, $publication);
return $publication;
}
}
// USAGE
$debugger = DebuggerEcho::getInstance();
$library = new Library($debugger);
$bookPublisher = new BookPublisher('PC');
$journalPublisher = new JournalPublisher('medicína');
$facade = new FacadePurchase($library);
$facade->addPublisher('PC', $bookPublisher);
$facade->addPublisher('MEDICINA', $journalPublisher);
$facade->purchase('PC', 460);
$facade->purchase('MEDICINA', 300);
<?php
// https://www.supercoders.in/2019/07/php-command-line-php-parsing-program_16.html
// https://misc.flogisoft.com/bash/tip_colors_and_formatting
// https://joshtronic.com/2013/09/02/how-to-use-colors-in-command-line-output/
$longopts = array(
"required:", // Required value
"optional::", // Optional value
"option", // No value
"opt", // No value
);
$options = getopt("", $longopts);
echo "\e[0;34;41mMerry Christmas!\e[0m\n";
echo "kunda";
echo "\033[31m some colored text \033[0m some white text \n";
echo "Normal \e[5mBlink \n";
echo "Normal \e[1mBold \n";
echo "Default \e[33mYellow \n";
/*!
* Check if an element is out of the viewport
* (c) 2018 Chris Ferdinandi, MIT License, https://gomakethings.com
* @param {Node} elem The element to check
* @return {Object} A set of booleans for each side of the element
*/
var isOutOfViewport = function (elem) {
// Get element's bounding
var bounding = elem.getBoundingClientRect();
// Check if it's out of the viewport on each side
var out = {};
out.top = bounding.top < 0;
out.left = bounding.left < 0;
out.bottom = bounding.bottom > (window.innerHeight || document.documentElement.clientHeight);
out.right = bounding.right > (window.innerWidth || document.documentElement.clientWidth);
out.any = out.top || out.left || out.bottom || out.right;
out.all = out.top && out.left && out.bottom && out.right;
return out;
};
// from bottom to top
// console.table({
// 'tooltipHeight': $tooltip.height(),
// 'offsetTop': offsetPos.y,
// 'positionTop': position.top,
// 'windowHeight': $(window).height(),
// 'documentHeight': $(document).height(),
// 'scrollTop': $(window).scrollTop(),
// });
if (offsetPos.y - $(window).scrollTop() + $tooltip.outerHeight(true) > $(window).height())
{
var moveUp = offsetPos.y - $tooltip.height() - 35;
$tooltip.css({
top: moveUp + "px"
})
}
// right side
var offset = $(this).offset();
var position = $(this).position();
var offsetPos = {
x: offset.left,
y: offset.top + 35,
}
// prevent overlapping on the right edge
if (offsetPos.x + tooltipSize.w >= winSize.w)
{
offsetPos.x = winSize.w - tooltipSize.w - gutter;
}
<?php
include "1.php";
/*
Definice
--------
Návrhový vzor Proxy kontroluje přístup k objektu pomocí zástupce, který se používá
místo vlastního objektu.
Pro implementaci zástupce typu Protection Proxy je nutné provést následující
kroky:
1. Vytvořit třídu, která implementuje veškerá rozhraní implementované třídou,
jejíž instance mají být chráněné.
2. Ve všech metodách delegovat volání na objekt, který provede požadovanou
úlohu.
3. Vytvořit potomka třídy z bodu 2 a v relevantních metodách implementovat
kontrolní mechanizmy.
*/
abstract class PublicationProxy implements Publication
{
protected $publication;
public function __construct(Publication $publication)
{
$this->publication = $publication;
}
public function open()
{
return $this->publication->open();
}
public function close()
{
return $this->publication->close();
}
public function setPageNumber($page)
{
return $this->publication->setPageNumber($page);
}
public function getPageNumber()
{
return $this->publication->getPageNumber();
}
public function getDailyRate($days = 1)
{
return $this->publication->getDailyRate($days);
}
public function getCategory()
{
return $this->publication->getCategory();
}
public function getPageCount()
{
return $this->publication->getPageCount();
}
}
class PrepaidPublicationProxy extends PublicationProxy
{
protected $startPage;
protected $endPage;
public function __construct(Publication $publication, $startPage, $endPage)
{
parent::__construct($publication);
$this->startPage = $startPage;
$this->endPage = $endPage;
}
public function setPageNumber($page)
{
if ($this->startPage > $page || $this->endPage < $page) {
throw new OutOfRangeException(
$page,
$this->startPage,
$this->endPage
);
}
return $this->publication->setPageNumber($page);
}
}
class OutOfRangeException extends \Exception
{
protected $page;
protected $startPage;
protected $endPage;
public function __construct($page, $startPage, $endPage)
{
$this->page = $page;
$this->startPage = $startPage;
$this->endPage = $endPage;
$this->message = sprintf(
"Požadovaná strana číslo %dse nenachází v předplaceném rozsahu stran %d - %d.",
$this->page,
$this->startPage,
$this->endPage
);
}
public function getPage()
{
return $this->page;
}
public function getStartPage()
{
return $this->startPage;
}
public function getEndPage()
{
return $this->endPage;
}
}
$book = new Book('medicína', 650);
$proxy = new PrepaidPublicationProxy($book, 261, 414);
$proxy->open();
try
{
$proxy->setPageNumber(300);
print "Kniha je otevřená na straně 300.\n";
$proxy->setPageNumber(115);
print "Kniha je otevřená na straně 115.\n";
}
catch (OutOfRangeException $e) {
print $e->getMessage() . "\n";
}
$proxy->close();
/*
Kniha je otevřená na straně 300.
Požadovaná strana číslo 115 se nenachází
v předplaceném rozsahu stran 261-414.
*/
/*!
* jQuery prototypal inheritance plugin boilerplate
* Author: Alex Sexton, Scott Gonzalez
* Further changes: @addyosmani
* Licensed under the MIT license
*/
// myObject - an object representing a concept that you want
// to model (e.g. a car)
var myObject = {
init: function( options, elem ) {
// Mix in the passed-in options with the default options
this.options = $.extend( {}, this.options, options );
// Save the element reference, both as a jQuery
// reference and a normal reference
this.elem = elem;
this.$elem = $(elem);
// Build the DOM's initial structure
this._build();
// return this so that we can chain and use the bridge with less code.
return this;
},
options: {
name: "No name"
},
_build: function(){
//this.$elem.html('<h1>'+this.options.name+'</h1>');
},
myMethod: function( msg ){
// You have direct access to the associated and cached
// jQuery element
console.log("myMethod triggered");
// this.$elem.append('<p>'+msg+'</p>');
}
};
// Object.create support test, and fallback for browsers without it
if ( typeof Object.create !== "function" ) {
Object.create = function (o) {
function F() {}
F.prototype = o;
return new F();
};
}
// Create a plugin based on a defined object
$.plugin = function( name, object ) {
$.fn[name] = function( options ) {
return this.each(function() {
if ( ! $.data( this, name ) ) {
$.data( this, name, Object.create(object).init(
options, this ) );
}
});
};
};
// Usage:
// With myObject, we could now essentially do this:
// $.plugin('myobj', myObject);
// and at this point we could do the following
// $('#elem').myobj({name: "John"});
// var inst = $('#elem').data('myobj');
// inst.myMethod('I am a method');
// jQuery Plugin Boilerplate
// A boilerplate for jumpstarting jQuery plugins development
// version 1.1, May 14th, 2011
// by Stefan Gabos
(function($) {
$.pluginName = function(element, options) {
var defaults = {
foo: 'bar',
onFoo: function() {}
}
var plugin = this;
plugin.settings = {}
var $element = $(element),
element = element;
plugin.init = function() {
plugin.settings = $.extend({}, defaults, options);
// code goes here
}
plugin.foo_public_method = function() {
// code goes here
}
var foo_private_method = function() {
// code goes here
}
plugin.init();
}
$.fn.pluginName = function(options) {
return this.each(function() {
if (undefined == $(this).data('pluginName')) {
var plugin = new $.pluginName(this, options);
$(this).data('pluginName', plugin);
}
});
}
})(jQuery);
// USAGE
$(document).ready(function() {
// attach the plugin to an element
$('#element').pluginName({'foo': 'bar'});
// call a public method
$('#element').data('pluginName').foo_public_method();
// get the value of a property
$('#element').data('pluginName').settings.foo;
});
<?php
include "1.php";
/*
Definice
--------
Návrhový vzor Decorator rozšiřuje daný objekt o novou funkčnost nebo změní stávající
metody za běhu programu. Tento návrhový vzor nabízí flexibilní alternativu
k vytváření potomků tříd.
Pro dosažení požadovaného výsledku jsou nutné následující kroky:
1. Vytvořit základní třídu pro dekorátory, která je stejného typu jako objekt,
který má být dekorovaný. Vytvořit potomka této třídy nebo v nové třídě
implementovat všechny metody rozhraní.
2. V základní třídě definovat konstruktor, jemuž bude možné předat dekorovaný
objekt. Tento objekt uložit ve třídě dekorátoru.
3. Implementovat všechny metody základní třídy takovým způsobem, že se
jejich volání bude delegovat na objekt, který se má dekorovat.
4. Implementovat libovolné konkrétní dekorátory, jež jsou potomky třídy
z bodu 3. Konkrétního chování dekorátoru se docílí přepsáním jednotlivých
metod.
5. Kombinací více dekorátorů lze dosáhnout jejich vzájemným dekorováním.
*/
abstract class PublicationDecorator implements Publication
{
protected $publication;
public function __construct(Publication $publication)
{
$this->publication = $publication;
}
public function open()
{
return $this->publication->open();
}
public function close()
{
return $this->publication->close();
}
public function setPageNumber($page)
{
return $this->publication->setPageNumber($page);
}
public function getPageNumber()
{
return $this->publication->getPageNumber();
}
public function getDailyRate($days = 1)
{
return $this->publication->getDailyRate($days);
}
public function getCategory()
{
return $this->publication->getCategory();
}
public function getPageCount()
{
return $this->publication->getPageCount();
}
public function __call($method, $args)
{
return call_user_func_array(
array($this->publication, $method), $args
);
}
public function providesMethod($method)
{
if (method_exists($this->publication, $method))
{
return TRUE;
}
if ($this->publication instanceof PublicationDecorator)
{
return $this->publication->providesMethod($method);
}
return FALSE;
}
public function getPublication()
{
return $this->publication;
}
}
class PublicationDecoratorAppendix extends PublicationDecorator
{
public function getDailyRate($days = 1)
{
$rate = $this->publication->getDailyRate($days);
return $rate + 2;
}
public function getPageCount()
{
$pageCount = $this->publication->getPageCount();
return $pageCount + 30;
}
}
// Použití
$book = new Book('medicína', 100);
$withAppendix = new PublicationDecoratorAppendix($book);
printf("Celkový počet stran s přílohou: %d\n",
$withAppendix->getPageCount()
);
printf("Denní sazba: %.2f Kč\n",
$withAppendix->getDailyRate()
);
/*
Celkový počet stran s přílohou: 130
Denní sazba: 12.00 Kč
*/
// Další decorator
class PublicationDecoratorNews extends PublicationDecorator
{
public function getDailyRate($days = 1)
{
$rate = $this->publication->getDailyRate($days);
return round($rate * 0.8, 2);
}
}
$newsWithAppendix = new PublicationDecoratorNews($withAppendix);
printf("Celkový počet stran s přílohou: %d\n",
$newsWithAppendix->getPageCount()
);
printf("Denní sazba: %.2f Kč\n",
$newsWithAppendix->getDailyRate()
);
/*
Celkový počet stran s přílohou: 130
Denní sazba: 9.60 Kč
*/
/*
Další využití
-------------
Lze doplnit i nové metody
*/
class PublicationDecoratorCd extends PublicationDecorator
{
protected $track = 1;
public function getTrack()
{
return $this->track;
}
public function setTrack($track)
{
$this->track = $track;
}
public function getDailyRate($days = 1)
{
$rate = $this->publication->getDailyRate($days);
return $rate * 1.3;
}
}
$book = new Book('italská kuchyně', 280);
$withCd = new PublicationDecoratorCd($book);
printf("Denní sazba: %.2f Kč\n", $withCd->getDailyRate());
$withCd->setTrack(10);
printf("Aktuální stopa: %d \n", $withCd->getTrack());
/*
Denní sazba: 13.00 Kč
Aktuální stopa: 10
*/
/*
Může vzniknout problém, že jiný dekorátor tyto metody nevidí,
odchytne se to pres __call, ale je to takové magické...
*/
$book = new Book('italská kuchyně', 280);
$withCd = new PublicationDecoratorCd($book);
$newsWithCd = new PublicationDecoratorNews($withCd);
printf("Denní sazba: %.2f Kč\n", $newsWithCd->getDailyRate());
$newsWithCd->setTrack(10);
// printf("Aktuální stopa: %d \n", $newsWithCd->getTrack());
/*
Denní sazba: 10.40 Kč
Aktuální stopa: 10
*/
/*
Dá se to vyřešit lépe...
viz vlastní metoda na existenci providesMethods()
*/
$book = new Book('italská kuchyně', 280);
$withCd = new PublicationDecoratorCd($book);
$newsWithCd = new PublicationDecoratorNews($withCd);
if ($newsWithCd->providesMethod('setTrack'))
{
var_dump($newsWithCd->getPublication());
$newsWithCd->setTrack(30);
}
printf("Aktuální stopa: %d \n", $newsWithCd->getTrack());
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<style>
.blocker
{
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
overflow: auto;
z-index: 1;
padding: 20px;
box-sizing: border-box;
background-color: #000;
background-color: #000000bf;
text-align: center;
}
.blocker::before
{
content: "";
display: inline-block;
height: 100%;
vertical-align: middle;
margin-right: -0.05em;
}
.modal
{
vertical-align: middle;
position: relative;
z-index: 2;
max-width: 500px;
box-sizing: border-box;
width: 90%;
background: #fff;
padding: 15px 30px
}
</style>
</head>
<body>
<!-- https://jquerymodal.com/ -->
<div class="jquery-modal blocker current">
<div class="modal" style="display: inline-block;">
<h1>Hello there!</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p><a href="#close-modal" rel="modal:close" class="close-modal ">Close</a></div>
</div>
</div>
</body>
</html>