在哪里填充数据?内部或外部方法



我在填充数据的地方有一个困境。

以下是2种计算报价总价的方法:

// example in javascript
function computePrice(quotation) {
    var totalPrice = 0.00;
    var items = quotation.getItems();
    for (var i = 0; i < items.length; i++) {
        totalPrice += items[i].getPrice();
    }
    return totalPrice;
}
QuotationDao.populateItems(quotation);
computePrice(quotation);

另一种写作方式是:

function computePrice(quotation) {
    var totalPrice = 0.00;
    // Populate items in the quotation from database
    QuotationDao.populateItems(quotation);
    var items = quotation.getItems();
    for (var i = 0; i < items.length; i++) {
        totalPrice += items[i].getPrice();
    }
    return totalPrice;
}
computePrice(quotation);

我问了我的同龄人并收到了不同的输入。

  1. 方法#1是正确的,因为除非该功能纯粹是出于检索目的而创建的,否则代码不应在功能中检索数据。

  2. 方法#1是正确的,因为它允许单元测试。

  3. 方法#2是正确的,因为在调用该方法之前不需要外部依赖,该方法具有较高的凝聚力。

  4. 所有方法都是不完整的,引用dao.PopulateItems(引号)应采用单独的方法,例如QuotationDao.getComputepriceData(引号),结果将结果传递到Computeprice(例如ComputePrice)(如ComputePrice(ComputePricedata);

您对我应该采取哪种路线有任何建议吗?

如果某人应用demeter的法律(也称为"最少知识的原理"和单个责任原则),那么人们想编写这样的代码:

Quotation q = dao.fetchQuotation(someCondition);
totalPrice = q.getTotalPrice(); //Computation inside it

如果计算有点复杂,并且不仅涉及在引号中添加各个项目的值,则可以使用单独的方法:

Quotation q = dao.fetchQuotation(someCondition);
totalPrice = PriceHelper.getTotalPrice(q); //Computation inside it

两种方法都是同样测试的(需要适当的模拟/存根)

如果您仍然感到困惑,那么,请问自己一个问题 - "哪种方法为我提供了易于理解的代码" - 每当我遇到这样的困境

您正在为数据总体方法使用不良方法结构QuotationDao.populateItems(quotation);。为什么不好?

  1. 它破坏了不变性。对于简单的方法(例如填充数据或生成数据),接受输入和返回结果将更有益,因为它可以重新计算,结果将是一致的。

  2. 该方法没有自明。您不知道数据类型的报价是什么,提前需要执行的内容,人数是什么,人口参数是什么。

  3. 它没有使用静态键入语言(例如Java/c#)来工作。他们需要将特定的对象类型作为参数传递。

我的建议是拥有2个不同的检索器或您所说的dao:

quotationDao.getQuotation = function(){
    var quotation = {};
    // populate quotation
    return quotation;
}
itemDao.getItems = function(quotation){
    var items = {};
    // get items
    return items;
}

接下来,您可以关注Wand Maker关于SRP和Law of Demeter的答案。但是他的答案仍然打破了Law of Demeter。它说:

  • 每个单元只能对其他单位具有有限的知识:仅与当前单元相关的单位。
  • 每个单位只能与朋友交谈;不要和陌生人说话。
  • 只与您的直系朋友交谈。

在您当前的实施中,价格计算的最接近的朋友将只是项目。他们不应该知道报价。因此,而不是使用

Quotation q = dao.fetchQuotation(someCondition);
totalPrice = q.getTotalPrice(); //Computation inside it
//or
Quotation q = dao.fetchQuotation(someCondition);
totalPrice = PriceHelper.getTotalPrice(q); //Computation inside it

而是使用:

Quotation q = dao.fetchQuotation(someCondition);
Items i = itemDao.fetchItem(quotation);
totalPrice = i.getTotalPrice(); //Computation inside it
//or
Quotation q = dao.fetchQuotation(someCondition);
Items i = itemDao.fetchItem(quotation);
totalPrice = PriceHelper.getTotalPrice(i); //Computation inside it

最新更新