该类使用openweathermap接收有关当前天气和预报的信息。我正在寻找任何类型的建议,但主要用于结构和风格改进建议:此方法构建API URL:
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;
}实际查询是通过以下方法完成的:
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;
}以下是所接收数据的反序列化:
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;
}这被消费者称为:
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页面上找到。
发布于 2016-08-28 07:14:56
BuildQueryURL法
这种方法的风格很差。它应该构建一个查询url,但是您给它一个名称-值-集合,您可以在方法中修改它!
你应该把它分成两种方法。
第一个只应该是UpdateParameters,而另一个BuildQueryURL只构建url,而不修改任何其他值并导致意外行为。如果我使用它,并发现它实际上也改变了参数,我会感到非常惊讶,尽管它的名字并不意味着任何类似的东西。
间期枚举
如果这是您的枚举,那么使这些值与相对路径完全一样,这样您就可以在没有开关的情况下调用.ToString()。如果不是的话,我会用字典来摆脱这个开关。
Execute & GetWeather方法
通常,当我们这样做时,当我们有一个out参数并返回一个bool或另一种类型的结果成功指示符时,我们将方法命名为TryDoSomething,因此在您的例子中,方法应该被称为TryExecuteQuery和TryGetWeather。
https://codereview.stackexchange.com/questions/139805
复制相似问题