Resumo : neste tutorial, você aprenderá como usar o padrão C# Façade para criar uma interface simples e limpa para um subsistema maior e mais complexo.
Introdução ao padrão C# Façade
O padrão Façade é um padrão de projeto estrutural que permite criar uma interface simplificada para um subsistema complexo.
O padrão Façade expõe apenas a funcionalidade necessária do subsistema subjacente, enquanto oculta os detalhes de implementação e as complexidades do subsistema.
O diagrama a seguir ilustra o padrão Façade:
Neste diagrama, as classes clientes interagem com uma interface simples (Facade) em vez de trabalharem diretamente com classes do subsistema. Isto torna o sistema mais flexível para que, quando as classes do subsistema forem alteradas, não seja necessário modificar as classes do cliente.
Para usar o padrão Façade na prática, você cria uma nova classe ou conjunto de classes que serve como interface para o subsistema existente.
Esta nova interface fornece um conjunto simplificado de métodos que as classes clientes utilizam para acessar a funcionalidade do subsistema. As classes clientes não precisam conhecer os detalhes da implementação nem interagir diretamente com as classes do subsistema.
Exemplo de padrão de fachada C#
O programa a seguir retorna a temperatura atual em Celsius com base em uma cidade. Ele usa três classes GeoLookupService
, WeatherService
e ConverterService
que fornecem pesquisa de geolocalização, previsão do tempo e serviços de conversão:
namespace FacacdePattern;
public class Location
{
public double Latitude
{
get; set;
}
public double Longitude
{
get; set;
}
public Location(double latitude, double longitude)
{
Latitude = latitude;
Longitude = longitude;
}
}
public class GeoLookupService
{
public Location GetLocationByCity(string city)
{
return new Location(15, 20);
}
}
public class WeatherService
{
public double GetCurrentTemperature(Location location) => new Random().Next(32, 115);
}
public class ConverterService
{
public double ConvertFToC(double f) => (f - 32) * 5 / 9;
}
public class Program
{
public static void Main(string[] args)
{
var geoLookupService = new GeoLookupService();
var location = geoLookupService.GetLocationByCity("San Jose");
var weatherService = new WeatherService();
var temperature = weatherService.GetCurrentTemperature(location);
var converterService = new ConverterService();
var temperatureInC = converterService.ConvertFToC(temperature);
Console.WriteLine($"The current temperature is {temperatureInC:F1}°C");
}
}
Linguagem de código: C# ( cs )
Saída:
The current temperature is 30.0°C
Linguagem de código: C# ( cs )
Como funciona.
Primeiro, defina a Location
classe que representa uma localização geográfica com latitude e longitude:
public class Location
{
public double Latitude
{
get; set;
}
public double Longitude
{
get; set;
}
public Location(double latitude, double longitude)
{
Latitude = latitude;
Longitude = longitude;
}
}
Linguagem de código: C# ( cs )
Segundo, defina a GeoLookupService
classe com um método GetLocationByCity()
que retorne um objeto Location para uma determinada cidade:
public class GeoLookupService
{
public Location GetLocationByCity(string city)
{
return new Location(15, 20);
}
}
Linguagem de código: C# ( cs )
Terceiro, defina a WeatherService
classe que retorna a temperatura atual em Fahrenheit de um local:
public class WeatherService
{
public double GetCurrentTemperature(Location location) => new Random().Next(32, 115);
}
Linguagem de código: C# ( cs )
O GetCurrentTemperature()
método retorna uma temperatura aleatória em Fahrenheit entre 32 e 115. Na prática, você pode chamar uma API para obter a temperatura atual com base na localização atual do usuário.
Quarto, defina a ConverterService
classe que converte Fahrenheit em Celsius:
public class ConverterService
{
public double ConvertFToC(double f) => (f - 32) * 5 / 9;
}
Linguagem de código: C# ( cs )
Por fim, use as classes acima na classe Client para exibir a temperatura atual em Celsius no console usando as classes de serviço acima:
public class Client
{
public static void Main(string[] args)
{
var geoLookupService = new GeoLookupService();
var location = geoLookupService.GetLocationByCity("San Jose");
var weatherService = new WeatherService();
var temperature = weatherService.GetCurrentTemperature(location);
var converterService = new ConverterService();
var temperatureInC = converterService.ConvertFToC(temperature);
Console.WriteLine($"The current temperature is {temperatureInC:F1}°C");
}
}
Linguagem de código: C# ( cs )
O programa funciona bem, exceto pelo fato de depender de muitos serviços do subsistema. Se um dos serviços for alterado, você precisará modificar a classe Client de acordo. Para tornar a classe Client mais flexível, você pode aplicar o padrão Façade.
Usando o padrão Fachada
Primeiro, defina uma interface IWeatherServiceFacade
:
public interface IWeatherServiceFacade
{
double GetCurrentTemperatureByCity(string city);
}
Linguagem de código: C# ( cs )
A IWeatherServiceFacade
interface possui um método GetCurrentTemperatureByCity()
que retorna a temperatura atual em Celsius de uma cidade.
Segundo, defina a WeatherServiceFacade
classe que implementa a WeatherServiceFacade
interface I:
public class WeatherServiceFacade : IWeatherServiceFacade
{
private readonly GeoLookupService _geoLookupService;
private readonly WeatherService _weatherService;
private readonly ConverterService _converterService;
public WeatherServiceFacade()
{
_geoLookupService = new GeoLookupService();
_weatherService = new WeatherService();
_converterService = new ConverterService();
}
public double GetCurrentTemperatureByCity(string city)
{
var location = _geoLookupService.GetLocationByCity(city);
var temperature = _weatherService.GetCurrentTemperature(location);
return _converterService.ConvertFToC(temperature);
}
}
Linguagem de código: C# ( cs )
O GetCurrentTemperatureByCity()
método do
primeiro utiliza o WeatherService
FacadeGeoLookupService
objeto para obter a localização de uma cidade. Em seguida, ele usa o WeatherService
objeto para obter a temperatura atual em Fahrenheit por localização. E, finalmente, usa UnitConvertService
para converter a temperatura de Fahrenheit para Celsius.
Agora, a Client
classe precisa usar o IWeatherServiceFacade
objeto para obter a temperatura atual de uma cidade chamando o GetCurrentTemperatureByCity()
método. Não precisa conhecer os serviços subjacentes:
public class Client
{
public static void Main(string[] args)
{
var weatherServiceFacade = new WeatherServiceFacade();
var temperatureInC = weatherServiceFacade.GetCurrentTemperatureByCity("San Jose");
Console.WriteLine($"The current temperature is {temperatureInC:F1}°C");
}
}
Linguagem de código: C# ( cs )
Juntando tudo.
namespace FacacdePattern;
public class Location
{
public double Latitude
{
get; set;
}
public double Longitude
{
get; set;
}
public Location(double latitude, double longitude)
{
Latitude = latitude;
Longitude = longitude;
}
}
public class GeoLookupService
{
public Location GetLocationByCity(string city)
{
return new Location(15, 20);
}
}
public class WeatherService
{
public double GetCurrentTemperature(Location location) => new Random().Next(32, 115);
}
public class ConverterService
{
public double ConvertFToC(double f) => (f - 32) * 5 / 9;
}
public interface IWeatherServiceFacade
{
double GetCurrentTemperatureByCity(string city);
}
public class WeatherServiceFacade : IWeatherServiceFacade
{
private readonly GeoLookupService _geoLookupService;
private readonly WeatherService _weatherService;
private readonly ConverterService _converterService;
public WeatherServiceFacade()
{
_geoLookupService = new GeoLookupService();
_weatherService = new WeatherService();
_converterService = new ConverterService();
}
public double GetCurrentTemperatureByCity(string city)
{
var location = _geoLookupService.GetLocationByCity(city);
var temperature = _weatherService.GetCurrentTemperature(location);
return _converterService.ConvertFToC(temperature);
}
}
public class Client
{
public static void Main(string[] args)
{
var weatherServiceFacade = new WeatherServiceFacade();
var temperatureInC = weatherServiceFacade.GetCurrentTemperatureByCity("San Jose");
Console.WriteLine($"The current temperature is {temperatureInC:F1}°C");
}
}
Linguagem de código: C# ( cs )
Resumo
- Use o padrão Façade para criar uma interface simples e limpa para subsistemas complexos para tornar seus aplicativos mais fáceis de manter e flexíveis.