2013-06-29 5 views
3

Я ищу советы по лучшей практике, как использовать инкапсуляцию при сохранении коллекций объектов в базе данных.Инкапсуляция против производительности базы данных

Например, вам необходимо сохранить дистрибьютора, который имеет коллекцию продуктов. Если вы держите инкапсуляцию и не испортите материал базы данных, относящийся к таблицам продуктов в классе дистрибьютора, вам нужно сделать слишком много обращений к базе данных для сохранения каждого отдельного продукта в цикле. Код будет выглядеть следующим образом:

class Distributor { 
    private $products; 
    function save() { 
    foreach ($products as $prod) { 
     // 10000 products = 10000 hits to the DB! Instead of only one! 
     $prod->save(); 
    } 
    } 
} 

С другой стороны, если вы хотите, чтобы оптимизировать запрос и сделать несколько строк Insert/InsertUpdate вы могли бы сделать что-то более сложное, как это:

class Distributor { 
    private $products; 
    $query = $dao->getInsertUpdateQueryInstance(); 
    foreach ($products as $prod) { 
    // Much extra code for implementing such an encapsulation. 
    $query->addRow($prod->getRow()); 
    } 
    $query->execute(); 
} 

Это означает, что вам нужно написать свой слой DAO с помощью специальных функций addRow().

Третья возможность, которую я вижу, - создать статический массив в классе Product, но это нарушает логическое разделение проблем. Теперь список продуктов хранится в том же классе Product, что и для его дистрибьютора.

class Distributor { 
    // I'm a distributor and I have nothing to do... 
} 
class Product { 
    private static $products; 
    function save() { 
    foreach (self::products as $prod) { 
     // add row 
    } 
    // persist 10000 rows 
    } 
} 

Инкапсуляция, но так уродливая! А что, если у вас есть несколько дистрибьюторов? Все продукты останутся в одном массиве?

Есть ли какой-либо не слишком сложный метод для достижения этого? Является ли ORM единственным способом?

ответ

1

Нет никакой проблемы при написании конкретного DAO для вашего дистрибьютора. Второе решение прекрасно, тогда как третье решение не следует рассматривать. Статический плохой.

Cheers

+0

Спасибо за ваш ответ! Наличие определенного DAO для каждого объекта означает два класса, которые знают о внутренних объектах вместо одного, я прав? Это плохо для ремонтопригодности? И почему статичность так плоха? А как насчет написания статических методов для сохранения групп объектов ('Product :: save ($ products)') и методов класса ('$ this-> save()') для сохранения экземпляров? В этом случае статично плохо? – bandolero

+0

Да, это то, что я имел в виду для конкретных дао. Если вы не хотите, чтобы дао знали частные механизмы класса, вы можете использовать шаблон посетителя в любом случае. Для статического материала я предлагаю вам использовать его только для поперечных вопросов, то есть для журнала, и т. Д. Статическая ситуация плохо при изменении глобальных полей, например. Это обычно приводит к проблемам ремонтопригодности, проблемам при распараллеливании и т. Д. – David

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