重构:结合两种方法

时间:2016-07-29 12:43:54

标签: c# refactoring

以前我有一种名为“搜索”的方法。这个方法实际上做了两件事:搜索/回馈找到的文章并计算结果集的一些数据。我现在创建了两个方法:一个用于搜索和回馈文章。其他搜索和计算数据。

仅执行搜索的第一种方法:

private List<SummaryRootEntity> search(int contentId,SearchModel query, bool includeTypeGroupFilters = true)
{
    cleanQuery(query);

    var inactiveForDays = getinactiveForDays();

    var searchProfileGroups = _manager.GetSearchProfileGroupsForSite(query.PropertyType);
    setLocationOfInterest(query);
    var searchBounds = _manager.GetSearchBounds(query.StreetID, query.SublocalityID);

    var shopsList = getShops();

    searchmodelDto.shops = shopsList;
    var filteredArticles = _articleService.Search(
        contentId,
        query,
        searchBounds,
        searchProfileGroups,
        inactiveForDays,
        includeTypeGroupFilters);

    // apply ordering
    var result = filteredArticles.ApplyOrdering(query.ForSaleOrRent, query.OrderBy, query.OrderDescending).ToList();

    return result;
}

第二个搜索和计算统计数据的人:

private List<SummaryRootEntity> searchWithStats(
    int contentId,
    SearchModel query,
    out FacetStatisticsModel stats,
    bool includeTypeGroupFilters = true)
{
    cleanQuery(query);

    var inactiveForDays = getinactiveForDays();

    var searchProfileGroups = _manager.GetSearchProfileGroupsForSite(query.Type);
    setLocationOfInterest(query);
    var searchBounds = _manager.GetSearchBounds(query.StreetID, query.SublocalityID);

    var shopsList = getShops();

    query.shops = shopsList;
    var filteredArticles = _articleService.Search(
        contentId,
        query,
        searchBounds,
        searchProfileGroups,
        inactiveForDays,
        includeTypeGroupFilters);

    var displaySearchResultSummary = getDisplaySearchResult ?? true;
    var stats = _articleService.GetStatistics(
        Site.ContentRoot.Id,
        shopsList,
        inactiveForDays,
        displaySearchResultSummary,
        searchProfileGroups,
        filteredArticles,
        query,
        searchBounds,
        Site.DefaultCultureInfo);

    // apply ordering
    var result = filteredArticles.ApplyOrdering(query.ForSaleOrRent, query.OrderBy, query.OrderDescending).ToList();

    return result;
}

第二种方法的开头与第一种方法相同。第二种方法通过“out”参数返回统计数据。

有没有办法以不同的方法计算统计数据?我可以从第二种方法中删除搜索,但之后我必须两次定义所有变量(inactiveForDays,searchProfileGroups,searchBounds)。

3 个答案:

答案 0 :(得分:2)

public Dictionry<string, object> PrepareQueryValues(SearchModel query)
{
     cleanQuery(query);

     Dictionary<string, object> dic = new Dictionary<string, object>();

     dic.Add("InactiveForDay", getinactiveForDays());
     dic.Add("SearchProfileGroups",_manager.GetSearchProfileGroupsForSite(query.PropertyType)); 
     dic.Add("SearchProfileGroups", setLocationOfInterest(query));
     dic.Add("SearchBounds", _manager.GetSearchBounds(query.StreetID, query.SublocalityID));
     dic.Add("ShopsList", getShops());

     return dic;         
}

所以你的第一种方法:

private List<SummaryRootEntity> search(int contentId,SearchModel query, bool includeTypeGroupFilters = true)
{
      Dictionary<string, object> dic = PrepareQueryValues(query);

      searchmodelDto.shops = (CastToProperType)dic["ShopsList"];
      var filteredArticles = _articleService.Search(
      contentId,
      query,
      (CastToProperType)dic["SearchBounds"],
      (CastToProperType)dic["SearchProfileGroups"],
      (CastToProperType)dic["InactiveForDays"],
      includeTypeGroupFilters);

      // apply ordering
      var result = filteredArticles.ApplyOrdering(query.ForSaleOrRent, query.OrderBy, query.OrderDescending).ToList();

      return result;

}

这样的事情应该有所帮助,但我认为这有点矫枉过正。

答案 1 :(得分:0)

只需使用搜索的返回值作为统计信息的参数:

所以签名如下:

private List<SummaryRootEntity> search(
    int contentId,
    SearchModel query, 
    bool includeTypeGroupFilters = true)
{
}

private FacetStatisticsModel searchWithStats(
    List<SummaryRootEntity> searchResults)
{
}  

你可以打电话

var searchResult = Search(x, y, z);

var searchResult = Search(x, y, z);
var statsResult = Stats(searchResult);

答案 2 :(得分:0)

两个函数都做同样的事情,只有一个函数做了一点额外的,对吗?

我只是将它们组合成一个函数,并在函数参数中添加一个额外的参数Decoder。然后你可以在函数内部使用if / else来执行每个案例所需的步骤。你没有像这样的重复代码,只有一个函数具有部分分支功能的所有情况。

您将获得实际的完整函数及其所有参数:

Boolean withStats

现在,这有点笨重,有out参数和boolean;你的普通搜索调用需要定义一个他们从未实际使用的'out'参数,并且两者都需要给出一个布尔值,从技术上可以推断出你是否要给出'out'参数。你可能更喜欢让电话像以前一样。

嗯,这很容易;只需进行两次重载,指向您刚才制作的相同中心功能。这会为你处理这些参数。

超载以使用统计信息调用搜索:

private List<SummaryRootEntity> search(
    Int32 contentId,
    SearchModel query,
    Boolean withStats,
    out FacetStatisticsModel stats,
    Boolean includeTypeGroupFilters = true)
{
    // I'll leave the actual combining part here up to you.
    // Shouldn't be too hard to implement.
}

重载以调用没有统计数据的搜索,这会使完全丢弃一个虚拟的'out'参数:

private List<SummaryRootEntity> search(
    Int32 contentId,
    SearchModel query,
    out FacetStatisticsModel stats,
    Boolean includeTypeGroupFilters = true)
{
    return search(contentId, query, true, out stats, includeTypeGroupFilters);
}

繁荣,代码压缩到一个功能。您当然必须确保执行“withStats = false”执行将out参数填入null。

相关问题