Estimated reading time: 6 minutes
A design pattern is not code that we can copy and insert into our program, as we can do with standard functions or libraries. The design pattern is a general concept capable of solving a particular problem. Basically a model whose details we can follow and implement a solution that fits the reality of our program.
Models are often confused with algorithms, because both concepts describe typical solutions to some known problems. While an algorithm defiIf there is always a clear set of actions that can achieve a certain goal, a model is a higher level description of a solution. Code from the same model applied to two different programs may be different.
Wanting to make an analogy, we can think of a cooking recipe: both have clear steps to achieve a goal. However, a model is more like a project, of which you can see what the result and its characteristics are, but the exact order of implementation depends on us who write the code.
Most patterns are described very formally so that people can reproduce them in many contexts. Let's see below the elements that are present in the description of a model:
A programmer can develop software without knowing the existence of design patterns. Many do, and for this reason they implement some schemes without knowing it. But then why should we spend time learning them?
Design patterns differ in complexity, level of detail, and scale of applicability throughout the designed system.
By analogy, we can make an intersection safer by installing a few traffic lights or building an entire multilevel interchange with underground passages for pedestrians.
The most basic, low-level models are often called idioms . They usually only apply to a single programming language.
The most universal and high-level models are architectural models . Developers can implement these patterns in virtually any language. Unlike other patterns, they can be used to design the architecture of an entire application.
Furthermore, all models can be classified according to their tried or purpose. The three main classes are:
Facade is a structural design pattern that provides a simplified interface to a library, framework, or any other complex set of classes.
Let's assume we need to make software work, based on a large set of objects that belong to a sophisticated library or framework. Normally, we would need to initialize all these objects, keep track of dependencies, execute methods in the correct order, and so on.
As a result, the business logic of the classes would become tightly coupled to the implementation details of third-party classes, making them difficult to understand and manage.
Una facade
is a class that provides a simple interface to a complex subsystem that contains many moving parts. A facade
may provide limited functionality compared to working directly with the subsystem. However, it only includes the features that customers really care about.
Have one facade
it is useful when we need to integrate the app with a sophisticated library that has dozens of features, but we only need a small part of its functionality.
For example, an app that uploads short funny videos featuring cats to social media could potentially use a professional video conversion library. However, all we really need is a class with the single method encode(filename, format)
. After creating such a class and connecting it to the video conversion library, we will have our first one facade
.
For example, the telephone operator of a call center is like a facade
. In fact, when we call a store's telephone service to place a telephone order, an operator is ours facade
towards all the services and departments of the store. The operator provides a simple voice interface to the ordering system, payment gateways and various delivery services.
Think about the Facade as a simple adapter for some complex subsystems. Facade
isolates the complexity within a single class and allows other application code to use the simple interface.
In this example, Facade
hides the complexity of the YouTube API and FFmpeg library from the client code. Instead of working with dozens of classes, the client uses a simple method on Facade.
<?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 will continue to provide cyber extortion incident response services. Coveware will offer forensics and remediation capabilities…
Predictive maintenance is revolutionizing the oil & gas sector, with an innovative and proactive approach to plant management.…
The UK CMA has issued a warning about Big Tech's behavior in the artificial intelligence market. There…
The "Green Houses" Decree, formulated by the European Union to enhance the energy efficiency of buildings, has concluded its legislative process with…