Оглавление:
Карта сайта:
Оглавление:
Карта сайта:
Фасад — это структурный паттерн, который предоставляет простой (но урезанный) интерфейс к сложной системе объектов, библиотеке или фреймворку.
Кроме того, что Фасад позволяет снизить общую сложность программы, он также помогает вынести код, зависимый от внешней системы в единственное место.
Применимость: Паттерн часто встречается в клиентских приложениях, написанных на PHP, которые используют классы-фасады для упрощения работы со сложными библиотеки или API.
\\
Признаки применения паттерна: Фасад угадывается в классе, который имеет простой интерфейс, но делегирует основную часть работы другим классам. Чаще всего, фасады сами следят за жизненным циклом объектов сложной системы.
Этот пример показывает структуру паттерна Фасад, а именно — из каких классов он состоит, какие роли эти классы выполняют и как они взаимодействуют друг с другом.
class Db { private $mysqli; private $host; private $user; private $pass; private $db; public function __construct($host, $user, $pass , $db) { $this->host = $host; $this->user = $user; $this->pass = $pass; $this->db = $db; $this->mysqli = null; } public function connect() { $this->mysqli = new \mysqli($this->host, $this->user, $this->pass, $this->db); if ($this->mysqli->connect_error) { die('Ошибка подключения (' . $this->mysqli->connect_errno . ') ' . $this->mysqli->connect_error); } } public function saveDocument($message) { $this->mysqli->query("INSERT INTO `messages` (text) VALUES ('".$message."')"); } } class Mail { private $to; private $subject; private $message; private $headers; public function __construct($to, $subject, $message, $headers) { $this->to = $to; $this->subject = $subject; $this->message = $message; $this->headers = $headers; } public function sendMessage($message) { mail($this->to, $this->subject, $this->message, $this->headers); } } class Log { private $filePath; public function __construct($filePath) { $this->filepath = $filePath; } public function addLog($message) { file_put_contents($this->filepath, $message.PHP_EOL, FILE_APPEND); } } class Document { private $db; private $log; private $mail; public function __construct(Db $db, Log $log, Mail $mail) { $this->db = $db; $this->log = $log; $this->mail= $mail; } public function save($message) { $this->db->connect(); $this->db->saveDocument($message); $this->log->addLog($message); $this->mail->sendMessage($message); } } $db = new Db('localhost','root','','patterns'); $log = new Log('logFile.txt'); $mail = new Mail('admin@admin.com','subject','message',''); $document = new Document($db, $log, $mail); $document->save("new document");
Результат выполнения
new document
В этом примере Фасад скрывает сложность API YouTube и библиотеки FFmpeg от клиентского кода. Вместо того, чтобы работать с десятками классов, клиент использует простой метод Фасада.
<?php namespace RefactoringGuru\Facade\RealWorld; /** * Фасад предоставляет единый метод загрузки видео с YouTube. Этот метод * скрывает всю сложность сетевого уровня PHP, API YouTube и библиотеки * преобразования видео (FFmpeg). */ class YouTubeDownloader { protected $youtube; protected $ffmpeg; /** * Бывает удобным сделать Фасад ответственным за управление жизненным циклом * используемой подсистемы. */ public function __construct(string $youtubeApiKey) { $this->youtube = new YouTube($youtubeApiKey); $this->ffmpeg = new FFMpeg(); } /** * Фасад предоставляет простой метод загрузки видео и кодирования его в * целевой формат (для простоты понимания примера реальный код * закомментирован). */ public function downloadVideo(string $url): void { echo "Fetching video metadata from youtube...\n"; // $title = $this->youtube->fetchVideo($url)->getTitle(); echo "Saving video file to a temporary file...\n"; // $this->youtube->saveAs($url, "video.mpg"); echo "Processing source video...\n"; // $video = $this->ffmpeg->open('video.mpg'); echo "Normalizing and resizing the video to smaller dimensions...\n"; // $video // ->filters() // ->resize(new FFMpeg\Coordinate\Dimension(320, 240)) // ->synchronize(); echo "Capturing preview image...\n"; // $video // ->frame(FFMpeg\Coordinate\TimeCode::fromSeconds(10)) // ->save($title . 'frame.jpg'); echo "Saving video in target formats...\n"; // $video // ->save(new FFMpeg\Format\Video\X264(), $title . '.mp4') // ->save(new FFMpeg\Format\Video\WMV(), $title . '.wmv') // ->save(new FFMpeg\Format\Video\WebM(), $title . '.webm'); echo "Done!\n"; } } /** * Подсистема API YouTube. */ class YouTube { public function fetchVideo(): string { /* ... */ } public function saveAs(string $path): void { /* ... */ } // ...дополнительные методы и классы... } /** * Подсистема FFmpeg (сложная библиотека работы с видео/аудио). */ class FFMpeg { public static function create(): FFMpeg { /* ... */ } public function open(string $video): void { /* ... */ } // ...more methods and classes... RU: ...дополнительные методы и классы... } class FFMpegVideo { public function filters(): self { /* ... */ } public function resize(): self { /* ... */ } public function synchronize(): self { /* ... */ } public function frame(): self { /* ... */ } public function save(string $path): self { /* ... */ } // ...more methods and classes... RU: ...дополнительные методы и классы... } /** * Клиентский код не зависит от классов подсистем. Любые изменения внутри кода * подсистем не будут влиять на клиентский код. Вам нужно будет всего лишь * обновить Фасад. */ function clientCode(YouTubeDownloader $facade) { // ... $facade->downloadVideo("https://www.youtube.com/watch?v=QH2-TGUlwu4"); // ... } $facade = new YouTubeDownloader("APIKEY-XXXXXXXXX"); clientCode($facade);
Output.txt: Результат выполнения
Fetching video metadata from youtube... Saving video file to a temporary file... Processing source video... Normalizing and resizing the video to smaller dimensions... Capturing preview image... Saving video in target formats... Done!