📜  在Python中使用 Facade 设计模式实现天气预报

📅  最后修改于: 2022-05-13 01:54:58.913000             🧑  作者: Mango

在Python中使用 Facade 设计模式实现天气预报

外观设计模式是Python中的设计模式,它为复杂的子系统提供简单的接口。当我们观察周围的世界时,我们总能找到外观设计模式。汽车就是最好的例子:您不需要了解发动机的工作原理。要操作发动机,您将获得一组简单的界面,例如转动点火钥匙启动发动机、使用方向盘转动车轮等。让我们来看看外观设计模式的优点。它们如下:

  • 保持客户端和子系统之间的松散耦合。
  • 更易于使用和测试
  • 为客户端代码提供更好更清晰的API
  • 它用一个简单的接口包装了一个复杂的子系统

天气预报实施

让我们进入实现部分。在这个应用程序中,我们获取一个城市的当前温度。为此,我们使用来自 openweathermap.org 资源的可用 API。在这里,在不使用外观设计模式的情况下,客户端必须经历许多复杂的任务,例如 API 调用、解析和检索必要的数据以及从 Kelvin 转换为 Celcius。如果客户端只需要调用一种方法来获取当前温度,那就更容易了。这就是我们通过外观设计模式实现的目标。

在进入源代码之前,让我们先看看代码设计模式。

在上图中,我们有一个由四个模块组成的子系统。如果客户端直接使用这些模块,就会失去灵活性。这是因为,如果更改了任何模块,则需要修改客户端代码,这会增加额外的复杂性。在使用外观设计模式时,客户端使用外观,其中外观调用子模块并将必要的详细信息返回给客户端。这种设计基于分解原理,将复杂的系统拆分为更小、更简单的子系统。

让我们看看每个模块的功能。

  • WeatherRetriever类向天气 API 端点发出请求并返回预测数据。
  • Crawler类抓取从 WeatherRetriever 类返回的数据,以 JSON 格式对其进行解码,并获取温度。
  • WeatherForecast类负责存储温度数据。
  • 最后, Converter类将温度从开尔文转换为摄氏度
Python3
import urllib
import urllib.request
import urllib.parse
import json
  
  
class WeatherRetriever(object):
    def __init__(self):
        self.api_url = 'https://samples.openweathermap.org/data/2.5/\
weather?q={},{}&appid=439d4b804bc8187953eb36d2a8c26a02'
  
    # takes input (city and country), produces a URL string,
    # generate HTTP request, and returns the data.
    def fetch_weather_data(self, city, country):
        city = urllib.parse.quote(city)
        url = self.api_url.format(city, country)
        return urllib.request.urlopen(url).read()
  
  
class Crawler(object):
    def crawl_weather_data(self, weather_data):
        data = json.loads(weather_data)
          
        # fetch the current temperature
        temp_data = data['main']['temp']
        return temp_data
  
  
class Converter(object):
    """ converts the temperature from kelvin to celcius """
  
    def from_kelvin_to_celcius(self, kelvin):
        return kelvin - 273.15
  
  
class WeatherForecast(object):
    def __init__(self, data):
        self.temperature = data
  
  
class FacadeDesign(object):
    def get_forecast(self, city, country):
        weather_retriever = WeatherRetriever()
        weather_data = weather_retriever.fetch_weather_data(city, country)
  
        crawl = Crawler()
        crawl_data = crawl.crawl_weather_data(weather_data)
        weather = WeatherForecast(crawl_data)
        converter = Converter()
        temp_celcius = converter.from_kelvin_to_celcius(weather.temperature)
        return temp_celcius
  
  
if __name__ == '__main__':
    facadeDesign = FacadeDesign()
    print("So today's forecast is about ",
          facadeDesign.get_forecast('London', 'uk'), "degrees")


输出:

外观设计模式提供了一个更高级别的接口,可以简化子系统的使用。外观设计没有添加任何新功能,相反,它充当了一个包装器,为访问复杂子系统提供了灵活性。