Article image
Sebastiao Junior
Sebastiao Junior20/08/2024 10:08
Compartilhe

Minha implementação do desafio de design patterns

    No desafio de design patterns, utilizei dois padrões amplamente reconhecidos no desenvolvimento de software e sugeridos pelo instrutor: Singleton e Facade. Esses padrões foram aplicados na construção de um aplicativo de consulta de condições climáticas que permite aos usuários obter informações meteorológicas atuais para qualquer cidade. A seguir, explico como o aplicativo foi implementado.

    O aplicativo é bem simples. Solicita ao usuário que insira o nome de uma cidade e exibe informações sobre a localização e as condições climáticas atuais para a localização fornecida. Se o usuário quiser sair do aplicativo a qualquer momento, basta digitar "sair".

    Para isso usei duas APIs:

    • Weatherstack é um serviço que fornece dados meteorológicos em tempo real para qualquer localização no mundo. A consulta é feita a partir das coordenadas geográficas (latitude e longitude). (https://weatherstack.com/)
    • Mapbox é utilizada no aplicativo para realizar geocodificação, ou seja, converter o nome de uma cidade ou endereço em coordenadas geográficas (latitude e longitude). Ela retorna resultados precisos, incluindo o tipo de local, relevância e contexto geográfico.(https://www.mapbox.com/)

    A classe mais importante do projeto é a `WeatherLocationService`. Ela foi implementada como um Singleton utilizando `enum`. Ela também age como uma fachada, encapsulando a complexidade de duas APIs: a Mapbox Geocoding API e a Weatherstack API. A Oracle recomenda o uso de `enum` para implementar o padrão Singleton em sua documentação oficial. Essa técnica é apontada como uma eficaz de assegurar uma instância única sendo thread-safe.

    public enum WeatherLocationService {
    
      INSTANCE;
    
      public CompletableFuture<String> getWeatherByLocationAsync(String location) throws UnsupportedEncodingException, IOException {
          if (geoLocationApiKey.get() == null || weatherApiKey.get() == null) config();
          if (location.isEmpty() || location.isBlank() || location == null) return CompletableFuture.completedFuture("Localidade vazia.");
    
    
          location = URLEncoder.encode(location, "UTF-8");
          var limit = "1";
          var urlGeoLocation = String.format("https://api.mapbox.com/geocoding/v5/mapbox.places/%s.json?access_token=%s&limit=%s", location, geoLocationApiKey, limit);
    
    
          // Faz a requisição de geolocalização de forma assíncrona
          return HttpJsonClient.INSTANCE.extractDataAsync(urlGeoLocation, ResponseGeoLocation.class)
              .thenCompose(geoLocation -> {
                  if (geoLocation == null || geoLocation.features().isEmpty()) {
                      return CompletableFuture.completedFuture("Não Encontrado.");
                  }
                  var latitude = geoLocation.getLatitude();
                  var longitude = geoLocation.getLongitude();
                  String urlWeather = String.format("https://api.weatherstack.com/current?access_key=%s&query=%s,%s", weatherApiKey, latitude, longitude);
                  // Faz a requisição do clima de forma assíncrona
                  return HttpJsonClient.INSTANCE.extractDataAsync(urlWeather, ResponseWeather.class)
                      .thenApply(weather -> {
                          if (weather == null) {
                              return "Não foi possível obter as condições meteorológicas.";
                          }
                         return String.format("%s\n%s", geoLocation.toString(), weather.toString());
                      });
              });
      }
    }
    

    Escrever o código desse desafio foi bem divertido. O emprego de design patterns resulta em uma arquitetura mais sólida, reutilizável e de fácil manutenção. O padrão Singleton assegura uma gestão eficiente das instâncias, e o Facade facilita a interação com sistemas externos ao ocultar suas complexidades. O resultado foi um código bem enxuto e organizado.

    Quem quiser dar uma olhada, o projeto está em https://github.com/gazolla/weatherylocation.

    Compartilhe
    Comentários (0)