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

时间:2015-05-10 14:08:30

标签: javascript

我对填充数据的位置感到困惑。

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

// 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. 所有方法都不完整,QuotationDao.populateItems(引用)应该在一个单独的方法中,如QuotationDao.getComputePriceData(引用),结果传递给computePrice,如computePrice(computePriceData);

  5. 您对我应该走哪条路线有什么建议吗?

2 个答案:

答案 0 :(得分:1)

如果应用Law of Demeter(也称为“最少知识原则”)和Single Responsibility Principle,则可以编写如下代码:

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

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

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

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

如果你仍然感到困惑,那么问问自己一个问题 - “哪种方法给我的代码很容易理解” - 每当我遇到这样的困境时,我发现“清洁代码”这本书真的很有用

答案 1 :(得分:1)

您正在为数据填充方法QuotationDao.populateItems(quotation);使用错误的方法结构。为什么不好?

  1. 它打破immutability。对于一个简单的方法,如填充数据或生成数据,接受输入和返回结果将更有益,因为它可以被重新调用,结果将是一致的。

  2. 该方法不是自我记录的。您不知道数据类型引用是什么,事先需要对引用执行什么,正在填充什么,填充参数是什么。

  3. 它不能用于java / C#等静态类型语言。他们需要将特定的对象类型作为参数传递。

  4. 我的建议是拥有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