Szacowany czas czytania: 6 minuti
Wzorzec projektowy nie jest kodem, który możemy skopiować i wstawić do naszego programu, tak jak możemy to zrobić w przypadku standardowych funkcji lub bibliotek. Wzorzec projektowy to ogólna koncepcja zdolna do rozwiązania konkretnego problemu. W zasadzie model, którego szczegóły możemy śledzić i wdrożyć rozwiązanie pasujące do rzeczywistości naszego programu.
Modele są często mylone z algorytmami, ponieważ oba pojęcia opisują typowe rozwiązania niektórych znanych problemów. Podczas gdy algorytm defiJeśli zawsze istnieje jasny zestaw działań, które mogą osiągnąć określony cel, model jest opisem rozwiązania wyższego poziomu. Kod z tego samego modelu zastosowany do dwóch różnych programów może się różnić.
Chcąc dokonać analogii, możemy pomyśleć o przepisie kulinarnym: oba mają jasne kroki, aby osiągnąć cel. Jednak model bardziej przypomina projekt, z którego widać jaki jest wynik i jakie są jego cechy, jednak dokładna kolejność realizacji zależy od nas, piszących kod.
Większość wzorców jest opisana bardzo formalnie, dzięki czemu ludzie mogą je odtworzyć w wielu kontekstach. Przyjrzyjmy się poniżej elementom, które występują w opisie modelu:
Programista może tworzyć oprogramowanie, nie wiedząc o istnieniu wzorców projektowych. Wielu tak robi i dlatego wdrażają pewne schematy, nie wiedząc o tym. Ale w takim razie dlaczego mielibyśmy poświęcać czas na ich naukę?
Wzorce projektowe różnią się złożonością, poziomem szczegółowości i skalą zastosowania w całym projektowanym systemie.
Analogicznie możemy zwiększyć bezpieczeństwo skrzyżowania instalując kilka sygnalizacji świetlnych lub budując cały wielopoziomowy węzeł przesiadkowy z podziemnymi przejściami dla pieszych.
Często nazywane są najbardziej podstawowe modele niskiego poziomu frazeologia . Zwykle dotyczą one tylko jednego języka programowania.
Najbardziej uniwersalne i wysokiej klasy modele to modele architektoniczne . Programiści mogą implementować te wzorce w praktycznie dowolnym języku. W przeciwieństwie do innych wzorców, można je wykorzystać do zaprojektowania architektury całej aplikacji.
Ponadto wszystkie modele można klasyfikować według ich wypróbowany lub cel. Trzy główne klasy to:
Fasada to strukturalny wzorzec projektowy, który zapewnia uproszczony interfejs do biblioteki, frameworku lub dowolnego innego złożonego zestawu klas.
Załóżmy, że musimy sprawić, aby oprogramowanie działało w oparciu o duży zestaw obiektów należących do zaawansowanej biblioteki lub frameworka. Zwykle musielibyśmy inicjować wszystkie te obiekty, śledzić zależności, wykonywać metody we właściwej kolejności i tak dalej.
W rezultacie logika biznesowa klas zostałaby ściśle powiązana ze szczegółami implementacji klas innych firm, co utrudniłoby ich zrozumienie i zarządzanie.
A facade
to klasa zapewniająca prosty interfejs do złożonego podsystemu zawierającego wiele ruchomych części. A facade
może zapewniać ograniczoną funkcjonalność w porównaniu do bezpośredniej pracy z podsystemem. Zawiera jednak tylko te funkcje, na których naprawdę zależy klientom.
Miej jeden facade
przydaje się, gdy potrzebujemy zintegrować aplikację z rozbudowaną biblioteką, która posiada dziesiątki funkcji, ale potrzebujemy tylko niewielkiej części jej funkcjonalności.
Na przykład aplikacja przesyłająca do mediów społecznościowych krótkie śmieszne filmy z kotami może potencjalnie skorzystać z profesjonalnej biblioteki konwersji wideo. Jednak tak naprawdę potrzebujemy tylko klasy z jedną metodą encode(filename, format)
. Po utworzeniu takiej klasy i podłączeniu jej do biblioteki konwersji wideo będziemy mieli naszą pierwszą facade
.
Na przykład operator telefoniczny centrum telefonicznego jest jak facade
. Tak naprawdę, gdy dzwonimy do obsługi telefonicznej sklepu, aby złożyć zamówienie telefoniczne, operator jest nasz facade
wobec wszystkich usług i działów sklepu. Operator zapewnia prosty interfejs głosowy do systemu zamówień, bramek płatniczych i różnych usług dostawy.
Myśleć o Fasada jako prosty adapter dla niektórych złożonych podsystemów. Facade
izoluje złożoność w obrębie jednej klasy i pozwala innemu kodowi aplikacji korzystać z prostego interfejsu.
W tym przykładzie Facade
ukrywa złożoność interfejsu API YouTube i biblioteki FFmpeg przed kodem klienta. Zamiast pracować z dziesiątkami klas, klient korzysta z prostej metody na Fasadzie.
<?php
namespace RefactoringGuru\Facade\RealWorld;
/**
* The Facade provides a single method for downloading videos from YouTube. This
* method hides all the complexity of the PHP network layer, YouTube API and the
* video conversion library (FFmpeg).
*/
class YouTubeDownloader
{
protected $youtube;
protected $ffmpeg;
/**
* It is handy when the Facade can manage the lifecycle of the subsystem it
* uses.
*/
public function __construct(string $youtubeApiKey)
{
$this->youtube = new YouTube($youtubeApiKey);
$this->ffmpeg = new FFMpeg();
}
/**
* The Facade provides a simple method for downloading video and encoding it
* to a target format (for the sake of simplicity, the real-world code is
* commented-out).
*/
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";
}
}
/**
* The YouTube API subsystem.
*/
class YouTube
{
public function fetchVideo(): string { /* ... */ }
public function saveAs(string $path): void { /* ... */ }
// ...more methods and classes...
}
/**
* The FFmpeg subsystem (a complex video/audio conversion library).
*/
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: ...дополнительные методы и классы...
}
/**
* The client code does not depend on any subsystem's classes. Any changes
* inside the subsystem's code won't affect the client code. You will only need
* to update the Facade.
*/
function clientCode(YouTubeDownloader $facade)
{
// ...
$facade->downloadVideo("https://www.youtube.com/watch?v=QH2-TGUlwu4");
// ...
}
$facade = new YouTubeDownloader("APIKEY-XXXXXXXXX");
clientCode($facade);
Ercole Palmeri
Coveware by Veeam będzie w dalszym ciągu świadczyć usługi reagowania na incydenty związane z wyłudzeniami cybernetycznymi. Coveware będzie oferować funkcje kryminalistyczne i naprawcze…
Konserwacja predykcyjna rewolucjonizuje sektor naftowo-gazowy dzięki innowacyjnemu i proaktywnemu podejściu do zarządzania zakładami.…
Brytyjskie CMA wydało ostrzeżenie dotyczące zachowań Big Tech na rynku sztucznej inteligencji. Tam…
Rozporządzenie w sprawie zielonych domów, opracowane przez Unię Europejską w celu zwiększenia efektywności energetycznej budynków, zakończyło proces legislacyjny…