我在填充数据的地方有一个困境。
以下是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是正确的,因为在调用该方法之前不需要外部依赖,该方法具有较高的凝聚力。
所有方法都是不完整的,引用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);
。为什么不好?
-
它破坏了不变性。对于简单的方法(例如填充数据或生成数据),接受输入和返回结果将更有益,因为它可以重新计算,结果将是一致的。
-
该方法没有自明。您不知道数据类型的报价是什么,提前需要执行的内容,人数是什么,人口参数是什么。
-
它没有使用静态键入语言(例如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