首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >气象API实现

气象API实现
EN

Code Review用户
提问于 2016-08-27 21:56:36
回答 1查看 353关注 0票数 3

该类使用openweathermap接收有关当前天气和预报的信息。我正在寻找任何类型的建议,但主要用于结构和风格改进建议:此方法构建API URL:

代码语言:javascript
复制
private Uri BuildQueryURL(Interval requestType, NameValueCollection parameters)
{
    if (parameters == null) parameters = new NameValueCollection();
    string relativePath = "";
    //set query//
    switch (requestType)
    {
        case Interval.Current:
            relativePath = "weather";
            break;
        case Interval.Forecast:
            relativePath = "forecast";
            break;
    }
    //add api key//
    parameters.Add("APPID", ApiKey);
    //if needed, add unit parameter//
    if (Units != Units.Default) parameters.Add("units", Units.ToString());
    //build uri
    var builder = new UriBuilder();
    builder.Scheme = "http://";
    builder.Host = "api.openweathermap.org";
    builder.Path = Path.Combine("data/2.5", relativePath);
    builder.Query = string.Join("&", parameters.AllKeys.Select((name) => string.Format("{0}={1}", HttpUtility.UrlEncode(name), HttpUtility.UrlEncode(parameters[name]))));
    return builder.Uri;
}

实际查询是通过以下方法完成的:

代码语言:javascript
复制
private RequestStatus Execute(Uri queryURI, out string queryResponse)
    {
        queryResponse = null;
        var status = RequestStatus.OK;
        try
        {
            queryResponse = _client.DownloadString (queryURI);
            //this methods parses the code parameter of the query response//
            status = CheckResponseCode(queryResponse);
        }
        catch(WebException) {
            status = RequestStatus.Failed;
        }
        return status;
    }

以下是所接收数据的反序列化:

代码语言:javascript
复制
 private CurrentWeather DeserializeCurrentWeather(string queryResponse)
    {
        var currentWeather = JsonConvert.DeserializeObject<CurrentWeather>(queryResponse);
        currentWeather.Units = this.Units;
        currentWeather.Country = CountryCodeHelper.ConvertToName((string)JObject.Parse(queryResponse).SelectToken("sys.country"));
        return currentWeather;
    }

这被消费者称为:

代码语言:javascript
复制
public RequestStatus GetWeatherByZip(int zip, string countryCode, out CurrentWeather result)
    {
        return GetWeather(new NameValueCollection() { { "zip", CombineQueryCountryCode(zip.ToString(), countryCode) } }, out result);
    }
public RequestStatus GetWeatherByCity(string city, string countryCode, out CurrentWeather result)
    {
        return GetWeather(new NameValueCollection() { { "q", CombineQueryCountryCode(city,countryCode) } }, out result);
    }
//...//
private RequestStatus GetWeather(NameValueCollection parameters, out CurrentWeather result)
    {
        string queryResponse;
        RequestStatus status = RequestStatus.OK;
        status = Execute(BuildQueryURL(Interval.Current, parameters), out queryResponse);
        result = DeserializeCurrentWeather(queryResponse);
        return status;
    }

我排除了异步方法和预测方法。完整的源代码可以在GitHub页面上找到。

EN

回答 1

Code Review用户

回答已采纳

发布于 2016-08-28 07:14:56

BuildQueryURL法

这种方法的风格很差。它应该构建一个查询url,但是您给它一个名称-值-集合,您可以在方法中修改它!

你应该把它分成两种方法。

第一个只应该是UpdateParameters,而另一个BuildQueryURL只构建url,而不修改任何其他值并导致意外行为。如果我使用它,并发现它实际上也改变了参数,我会感到非常惊讶,尽管它的名字并不意味着任何类似的东西。

间期枚举

如果这是您的枚举,那么使这些值与相对路径完全一样,这样您就可以在没有开关的情况下调用.ToString()。如果不是的话,我会用字典来摆脱这个开关。

Execute & GetWeather方法

通常,当我们这样做时,当我们有一个out参数并返回一个bool或另一种类型的结果成功指示符时,我们将方法命名为TryDoSomething,因此在您的例子中,方法应该被称为TryExecuteQueryTryGetWeather

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/139805

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档