我对填充数据的位置感到困惑。
以下是两种计算报价总价的方法:
// 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是正确的,因为在调用方法之前不需要外部依赖,该方法具有很高的内聚力。
所有方法都不完整,QuotationDao.populateItems(引用)应该在一个单独的方法中,如QuotationDao.getComputePriceData(引用),结果传递给computePrice,如computePrice(computePriceData);
您对我应该走哪条路线有什么建议吗?
答案 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);
使用错误的方法结构。为什么不好?
它打破immutability。对于一个简单的方法,如填充数据或生成数据,接受输入和返回结果将更有益,因为它可以被重新调用,结果将是一致的。
该方法不是自我记录的。您不知道数据类型引用是什么,事先需要对引用执行什么,正在填充什么,填充参数是什么。
它不能用于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