代码之家  ›  专栏  ›  技术社区  ›  DaveDev

如何使这两个几乎相同的代码块可重用?

  •  4
  • DaveDev  · 技术社区  · 14 年前

    我需要关于如何使下面两个代码块可重用的建议。我必须生成另一个资金表,在执行此操作时,我想创建funds table.ascx部分视图,所有需要显示资金表的视图都可以使用该视图。

    // Inherits="System.Web.Mvc.ViewPage<CompanyViewModel> // this is a company
    <%foreach (var fund in Model.PageFunds){%>
    
        <% foreach (var shareClass in fund.ShareClasses) {%>
    
            <tr class="shareclass">
                <td>
                    // displays an image if the ViewModel's Company is not unlisted
                    <%= Html.TearsheetImage((Model.Company.ListingType != ListingType.UNLISTED))%>
                </td>
            </tr>
    <% } }%>
    

    // Inherits="System.Web.Mvc.ViewPage<GroupViewModel> // this is a group of companies
    <%foreach (var fund in Model.PageFunds){%>
    
        <% foreach (var shareClass in fund.ShareClasses) {%>
    
            <tr class="shareclass">
                <td>
                    // displays an image if any Company in the ViewModel's 
                    // List<Company> is not unlisted
                    <%= Html.TearsheetImage(
                            (Model.Companies.WithCompanyId(fund.Company.Id) != ListingType.UNLISTED))%>
                </td>
            </tr>
    <% } }%>
    

    我想我需要把这些区别从某个地方抽象出来,但我不知道该把它放在哪里。这里有什么我应该遵循的经验法则吗?

    都应该 CompanyViewModel 和; GroupViewModel 实现一个接口来决定该项是否未列出?另外,我的fundTable.ascx应该是什么类型?我想两者都是 公司视图模型 和; 群组视图模型 可以延长 FundViewModel (或是别的什么)我可以让FundTable成为 ViewUserControl<FundViewModel> 但我不认为这会起作用,因为决定是否显示图像所需的功能需要来自 公司视图模型 和; 群组视图模型 独立地。

    另外,我越想这件事,我就越狡猾地欺骗自己!有什么想法或建议吗?谢尔斯

    2 回复  |  直到 14 年前
        1
  •  3
  •   jwsample    14 年前

    如果我读得对,代码只在决定是否显示图像的方式上有所不同。

    如果这是正确的,这是一个完美的地方做一点功能性编程!

    为.ascx创建视图模型。我们称之为资金稳定型。

    它将具有两个属性:

    Func<PageFund,bool> ShowImage {get;set;}
    IEnumerable PageFund Funds {get;set;}
    

    将fundStable.ascx强类型化为此对象。

    现在,是否显示的逻辑可以传入:

    FundsTable ft = new FundsTable();
    ft.ShowImage = f => f.SomeCombinationOfLogic == SomeOtherThing; //<-- Your function can be anything that returns a bool
    

    现在你可以做到:

    <% foreach (var shareClass in fund.ShareClasses) {%>
    
        <tr class="shareclass">
            <td>
                // displays an image if any Company in the ViewModel's 
                // List<Company> is not unlisted
               <% if(Model.ShowImage(fund)) {%>
                   <%= Html.TearsheetImage(fund)%>
               <% } %>
            </td>
        </tr>
    

    现在,我很难知道类是如何相互关联的,所以您可能需要改变类型和逻辑,但是这样的方法应该有效。为表设置视图模型时,只需传递确定是否显示图像的函数。如果Tearsheet查找需要这种复杂性,请添加另一个func属性。

        2
  •  0
  •   mare    14 年前

    对我来说,这样一个问题的根源在于这样一个事实:公司视图模型和公司组视图模型本质上是相同的(或者应该是相同的),而你不知何故,可能是无意中,设法从中创建了两个不同的视图模型。一般的逻辑是,一组公司应该 List<CompanyViewModel> . 可以将列表发送到视图或视图用户控件。您不必为它发明一个新的ViewModel类,只需将集合作为属性包含在该类中即可。

    看看你在评论的两行中写了什么,想想看。