Beräknad lästid: 6 minuter
Ett designmönster är inte kod som vi kan kopiera och infoga i vårt program, som vi kan göra med standardfunktioner eller bibliotek. Designmönstret är ett allmänt koncept som kan lösa ett visst problem. I grund och botten en modell vars detaljer vi kan följa och implementera en lösning som passar verkligheten i vårt program.
Modeller förväxlas ofta med algoritmer, eftersom båda begreppen beskriver typiska lösningar på några kända problem. Medan en algoritm defiOm det alltid finns en tydlig uppsättning åtgärder som kan uppnå ett visst mål, är en modell en beskrivning av en lösning på högre nivå. Kod från samma modell som tillämpas på två olika program kan vara olika.
Om vi vill göra en analogi kan vi tänka oss ett matlagningsrecept: båda har tydliga steg för att uppnå ett mål. En modell är dock mer som ett projekt, där du kan se vad resultatet och dess egenskaper är, men den exakta implementeringsordningen beror på oss som skriver koden.
De flesta mönster beskrivs väldigt formellt så att människor kan återge dem i många sammanhang. Låt oss se nedan vilka element som finns i beskrivningen av en modell:
En programmerare kan utveckla mjukvara utan att känna till existensen av designmönster. Många gör det, och av denna anledning implementerar de vissa system utan att veta om det. Men varför ska vi då lägga tid på att lära oss dem?
Designmönster skiljer sig i komplexitet, detaljnivå och tillämpbarhetsskala genom hela det designade systemet.
I analogi kan vi göra en korsning säkrare genom att installera några trafikljus eller bygga en hel trafikplats i flera plan med underjordiska passager för fotgängare.
De mest grundläggande, lågnivåmodellerna kallas ofta idiom . De gäller vanligtvis bara ett enda programmeringsspråk.
De mest universella och högnivåmodellerna är arkitektoniska modeller . Utvecklare kan implementera dessa mönster på praktiskt taget alla språk. Till skillnad från andra mönster kan de användas för att designa arkitekturen för en hel applikation.
Dessutom kan alla modeller klassificeras efter deras försökte eller syfte. De tre huvudklasserna är:
fasaden är ett strukturellt designmönster som ger ett förenklat gränssnitt till ett bibliotek, ramverk eller någon annan komplex uppsättning klasser.
Låt oss anta att vi måste få programvara att fungera, baserat på en stor uppsättning objekt som tillhör ett sofistikerat bibliotek eller ramverk. Normalt skulle vi behöva initiera alla dessa objekt, hålla reda på beroenden, köra metoder i rätt ordning och så vidare.
Som ett resultat skulle klassernas affärslogik bli tätt kopplad till implementeringsdetaljerna för tredjepartsklasser, vilket gör dem svåra att förstå och hantera.
en facade
är en klass som ger ett enkelt gränssnitt till ett komplext delsystem som innehåller många rörliga delar. A facade
kan ge begränsad funktionalitet jämfört med att arbeta direkt med delsystemet. Den innehåller dock bara de funktioner som kunderna verkligen bryr sig om.
Har en facade
det är användbart när vi behöver integrera appen med ett sofistikerat bibliotek som har dussintals funktioner, men vi behöver bara en liten del av dess funktionalitet.
Till exempel kan en app som laddar upp korta roliga videor med katter till sociala medier potentiellt använda ett professionellt videokonverteringsbibliotek. Men allt vi egentligen behöver är en klass med den enda metoden encode(filename, format)
. Efter att ha skapat en sådan klass och kopplat den till videokonverteringsbiblioteket kommer vi att ha vår första facade
.
Till exempel är telefonoperatören för ett callcenter som en facade
. Faktum är att när vi ringer en butiks telefontjänst för att göra en telefonbeställning är en operatör vår facade
mot alla tjänster och avdelningar i butiken. Operatören tillhandahåller ett enkelt röstgränssnitt till beställningssystemet, betalningsgateways och olika leveranstjänster.
Tänka på fasaden som en enkel adapter för vissa komplexa delsystem. Facade
isolerar komplexiteten inom en enda klass och tillåter annan applikationskod att använda det enkla gränssnittet.
I det här exemplet, Facade
döljer komplexiteten hos YouTube API och FFmpeg-biblioteket från klientkoden. Istället för att arbeta med dussintals klasser använder kunden en enkel metod på Fasad.
<?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 kommer att fortsätta att tillhandahålla svarstjänster för cyberutpressning. Coveware kommer att erbjuda kriminaltekniska och saneringsmöjligheter...
Förutsägande underhåll revolutionerar olje- och gassektorn, med ett innovativt och proaktivt förhållningssätt till anläggningsförvaltning.…
UK CMA har utfärdat en varning om Big Techs beteende på marknaden för artificiell intelligens. Där…
Dekretet "Gröna hus", formulerat av Europeiska unionen för att förbättra energieffektiviteten i byggnader, har avslutat sin lagstiftningsprocess med...