2015-05-10 2 views
1

У меня есть дилемма о том, где заполнить данные.Где заполнять данные? Внутренний или внешний метод?

Ниже приведены два вида методов, чтобы вычислить общую стоимость цитаты:

// 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);

У вас есть какие-либо советы относительно того, какой маршрут я должен предпринять?

ответ

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 

Оба подхода в равной степени проверяемый (соответствующий издевается/будут необходимы окурки)

Если вы все еще чувствуете, запутался, то, задайте себе вопрос - «какой подход дает мне код, который легко понять» - я нашел книгу «Чистый код» действительно полезно всякий раз, когда я столкнулся с такой дилеммой

+0

Благодаря палочки. но erm .. где бы вы заполнили позиции котировки? Внутри getTotalPrice или fetchQuotation или другая строка между такими: Котировка q = DAO.fetchQutation (someCondition); DAO.populateQuotationItems (q); totalPrice = q.getTotalPrice(); – bryan

+0

Что делает populateQuotation? –

+0

Хмм, 1 котировка обычно имеет N позиций, таких как продукт, количество, цены. populateQuotationItems будет заполнять элементы конкретной цитаты. Только после того, как население может вычислитьЦена работы. Это связано с тем, что без населения котировка будет содержать 0 элементов, поскольку они не были получены из базы данных. – bryan

1

Вы используя структуру плохого метода для вашего метода популяции данных QuotationDao.populateItems(quotation);. Почему это плохо?

  1. It breaks immutability. Для простого метода, такого как заполнение данных или генерирование данных, принятие результата ввода и возврата будет более выгодным, поскольку его можно повторно вызвать, и результат будет согласован.

  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; 
} 

Далее, вы можете следить за ответ Жезл Создателя о 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 
+0

Erm .. язык, который я использую, - это jscript, поэтому он довольно слабо типизирован. У меня есть два метода, которые вы предлагаете, но я реализую метод populateItems в качестве обертки, чтобы связать элементы с цитатой, чтобы я мог выполнить вызов quotation.getItems(). Основываясь на предложениях, которые вы предоставляете в качестве дополнения к производителю палочек, похоже, что вы также предлагаете, чтобы население предметов делалось вне метода getTotalPrice. – bryan

+0

Действительно. 'getTotalPrice' связан только с' items', поэтому нет смысла включать/передавать 'quotation'' getTotalPrice'. Если котировка не участвует в расчете цены, только тогда она будет передана. – Fendy

+0

Предположим, что котировка принимает участие в расчете цены, а затем следует заполнить. Делается вне getTotalPrice или внутри? – bryan

Смежные вопросы