Architecture/Design 与接口(重构帮助)
Architecture/Design with Interfaces (Refactoring help)
我需要你的帮助来解决我不满意的设计。
该应用程序正在使用 RSS 新闻(文章的 RSS,以及每篇文章的评论的 RSS)。
我制作了一个名为 IDataService 的接口,它提供了数据提供者的基本行为。
public interface IDataService
{
Task<List<Item>> GetItemsAsync(string url, IItemsParser parser);
Task<List<Comment>> GetItemCommentsAsync(string url, ICommentsParser parser);
}
如您所见,每个函数都将 Web 服务 url(在我的例子中是 RSS 提要 url)和一些解析器的接口作为参数,该接口知道如何处理数据。
这些是两个解析的接口:
public interface IItemsParser
{
List<Item> ParseRawData(string rawData);
}
public interface ICommentsParser
{
List<Comment> ParseRawData(string rawData);
}
现在让我们具体一点,这是实现 class:
public class MyRSSDataService : IDataService
{
public async Task<List<Item>> GetItemsAsync(string url, IItemsParser parser)
{
using (var httpClient = new HttpClient())
{
var response = await httpClient.GetAsync(new Uri(url));
if (response.IsSuccessStatusCode)
{
var jsonResponse = await response.Content.ReadAsStringAsync();
List<Item> items = parser.ParseRawData(jsonResponse);
return items;
}
else
{
throw new NetworkConnectionException(response.StatusCode.ToString());
}
}
}
public async Task<List<Comment>> GetItemCommentsAsync(string url, ICommentsParser parser)
{
using (var httpClient = new HttpClient())
{
var response = await httpClient.GetAsync(new Uri(url));
if (response.IsSuccessStatusCode)
{
var jsonResponse = await response.Content.ReadAsStringAsync();
List<Comment> comments = parser.ParseRawData(jsonResponse);
return comments;
}
else
{
throw new NetworkConnectionException(response.StatusCode.ToString());
}
}
}
}
我觉得我真的违反了DRY原则,而且我对我做的看起来如此相似的界面感觉不太好。
使用泛型:
public interface IDataService
{
Task<List<T>> GetDataAsync<T>(string url, IParser<T> parser);
}
public interface IParser<T>
{
List<T> ParseRawData(string rawData);
}
那么您的实现如下所示:
public class DataService : IDataService
{
public async Task<List<T>> GetDataAsync<T>(string url, IParser<T> parser)
{
// Do work
return parser.ParseRawData("blah");
}
}
public class ItemParser : IParser<Item>
{
public List<Item> ParseRawData(string rawData)
{
// Do work
}
}
public class CommentParser : IParser<Comment>
{
public List<Comment> ParseRawData(string rawData)
{
// Do work
}
}
现在使用起来就这么简单:
var x = new DataService();
var y = new ItemParser();
await x.GetDataAsync("", y);
var z = new CommentParser();
await x.GetDataAsync("", z);
我需要你的帮助来解决我不满意的设计。 该应用程序正在使用 RSS 新闻(文章的 RSS,以及每篇文章的评论的 RSS)。
我制作了一个名为 IDataService 的接口,它提供了数据提供者的基本行为。
public interface IDataService
{
Task<List<Item>> GetItemsAsync(string url, IItemsParser parser);
Task<List<Comment>> GetItemCommentsAsync(string url, ICommentsParser parser);
}
如您所见,每个函数都将 Web 服务 url(在我的例子中是 RSS 提要 url)和一些解析器的接口作为参数,该接口知道如何处理数据。
这些是两个解析的接口:
public interface IItemsParser
{
List<Item> ParseRawData(string rawData);
}
public interface ICommentsParser
{
List<Comment> ParseRawData(string rawData);
}
现在让我们具体一点,这是实现 class:
public class MyRSSDataService : IDataService
{
public async Task<List<Item>> GetItemsAsync(string url, IItemsParser parser)
{
using (var httpClient = new HttpClient())
{
var response = await httpClient.GetAsync(new Uri(url));
if (response.IsSuccessStatusCode)
{
var jsonResponse = await response.Content.ReadAsStringAsync();
List<Item> items = parser.ParseRawData(jsonResponse);
return items;
}
else
{
throw new NetworkConnectionException(response.StatusCode.ToString());
}
}
}
public async Task<List<Comment>> GetItemCommentsAsync(string url, ICommentsParser parser)
{
using (var httpClient = new HttpClient())
{
var response = await httpClient.GetAsync(new Uri(url));
if (response.IsSuccessStatusCode)
{
var jsonResponse = await response.Content.ReadAsStringAsync();
List<Comment> comments = parser.ParseRawData(jsonResponse);
return comments;
}
else
{
throw new NetworkConnectionException(response.StatusCode.ToString());
}
}
}
}
我觉得我真的违反了DRY原则,而且我对我做的看起来如此相似的界面感觉不太好。
使用泛型:
public interface IDataService
{
Task<List<T>> GetDataAsync<T>(string url, IParser<T> parser);
}
public interface IParser<T>
{
List<T> ParseRawData(string rawData);
}
那么您的实现如下所示:
public class DataService : IDataService
{
public async Task<List<T>> GetDataAsync<T>(string url, IParser<T> parser)
{
// Do work
return parser.ParseRawData("blah");
}
}
public class ItemParser : IParser<Item>
{
public List<Item> ParseRawData(string rawData)
{
// Do work
}
}
public class CommentParser : IParser<Comment>
{
public List<Comment> ParseRawData(string rawData)
{
// Do work
}
}
现在使用起来就这么简单:
var x = new DataService();
var y = new ItemParser();
await x.GetDataAsync("", y);
var z = new CommentParser();
await x.GetDataAsync("", z);