【问题标题】:How does abstractions help in DRY?抽象如何帮助 DRY?
【发布时间】:2018-02-17 16:07:59
【问题描述】:

当我们搜索"Don't repeat yourself" on Wikipedia时,第一句话是:

在软件工程中,不要重复自己DRY)是 旨在减少软件重复的软件开发 模式,用抽象代替它们......

我知道软件工程中的抽象意味着隐藏API行为如何实现的实现复杂性,但是这句话中的“抽象”似乎不是我以前所知道的。有人可以向我解释抽象在这里的含义吗?能举个例子就更好了。

【问题讨论】:

  • 隐藏实现细节是封装而不是抽象
  • @apokryfos 好的,我将实现细节更改为实现复杂性
  • 这仍然不是抽象。抽象是没有隐藏的。只是简化。
  • @apokryfos stackoverflow.com/questions/11965929/… 那么这篇文章中投票率最高的答案错了吗?
  • 不知道为什么它被否决了,对于这些标签来说这是一个合理的问题,尽管它可能只是对条款的误解。

标签: oop dry software-design


【解决方案1】:

我知道软件工程中的抽象意味着隐藏 API 的行为如何实现的实现复杂度

是的,这意味着 (absstraction@wikipedia) 和完全相同的概念也可以用来减少重复!或者换句话说,它可以用来练习 DRY。

让我试着用一个例子来解释一下。首先我会展示非 DRY 代码(没有抽象),然后我会尝试使用抽象来减少重复。

假设您想根据申请人填写的申请表详细信息构建一个电子邮件视图模型,并且有一个电子邮件视图类使用此 emailViewModel 来显示申请表中的所有非空详细信息。你可以像下面的例子那样写(第一次尝试)

public class ApplicationForm
{
        public AddressDetail AddressDetail { get; set; }
        public CustomerDetail CustomerDetail { get; set; }
        public ProductDetail ProductDetail { get; set; }
}

public class EmailViewModel
{
    public EmailViewModel(ApplicationForm applicationForm)
    {
        Address = GetAddressDetail(applicationForm.AddressDetail);
        Customer = GetCustomerDetail(applicationForm.CustomerDetail);
        Product = GetProductDetail(applicationForm.ProductDetail);
    }

    public string Address { get; set; }
    public string Customer { get; set; }
    public string Product { get; set; }
}

//view code assume razor view
@if(Model.Address!=null)
{
    // method for showing address
}
@if(Model.Customer!=null)
{
    // method for showing customer
}
//and other properties

我把上面的代码保持得很简单;只有三个属性并且没有显示转换方法的声明。如果有 50 个属性会怎样!在第一种方法中,您将在三个地方进行繁琐的更改。现在我将向您展示如何创建接口(一种抽象方式)实现 DRY 的第二个示例代码。

    interface IFormDetail
{
    IFormDetailView GetDetail();
}
interface IFormDetailView
{
    string ShowView();
}

public class ApplicationForm
{
        public List<IFormDetail> FormDetails {get;set;}
}

public class EmailViewModel
{
    public EmailViewModel(ApplicationForm applicationForm)
    {
        if(applicationForm.FormDetails!=null)
        {
            FormDetails = new List<IFormDetailView>();
            foreach(var detail in applicationForm.FormDetails)
            {
                FormDetails.Add(detail.GetDetail());
            }
        }
    }

    public List<IFormDetailView> FormDetails { get; set; }

}

//view code assume razor view
@f(Model.FormDetails!=null)
{
    foreach(var detail in Model.FormDetails){
        detail.ShowView();
    }
}

在第二个代码示例中,当您拥有一个新属性时,您只需在创建新的应用程序表单属性时进行一次更改。

因此,虽然我们隐藏了细节呈现方式等的复杂性,但我们也在利用它来减少重复。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-09
    • 2013-05-28
    • 1970-01-01
    相关资源
    最近更新 更多