2009-02-27 4 views
3

Работая над конкретным приложением, я продолжаю писать очень похожие запросы снова и снова. Они не совсем то же самое, но имеют очень схожую форму и встроены в почти идентичные куски кода, , например.,DRY и аналогичные запросы

$Mysqli = new mysqli; 
if ($Stmt = $Mysqli->prepare("SELECT foo 
           FROM tblFoo 
           WHERE something = ?")) { 
    $Stmt->bind_param('s', $this->_something); 
    $Stmt->execute(); 
    if (0 != $Stmt->errno) 
     throw new Exception("blah, blah, blah"); 
    $Stmt->bind_result($foo); 
    while ($Stmt->fetch()){ 
     $this->_foos[] = new Foo($foo); 
    } 
    $Stmt->close(); 
    } else { 
     throw new Exception("blah, blah, blah");); 
    } 
} 

, а потом, где-то еще ...

$Mysqli = new mysqli; 
if ($Stmt = $Mysqli->prepare("SELECT bar, baz 
           FROM tblBar 
           WHERE somethingElse = ?")) { 
    $Stmt->bind_param('s', $this->_somethingElse); 
    $Stmt->execute(); 
    if (0 != $Stmt->errno) 
     throw new Exception("blah, blah, blah"); 
    $Stmt->bind_result($bar, $baz); 
    while ($Stmt->fetch()){ 
     // do something else with $bar and $baz 
    } 
    $Stmt->close(); 
    } else { 
     throw new Exception("blah, blah, blah");); 
    } 
} 

... а потом еще и в другом месте другой ... и т.д.

Является ли это реальное нарушение DRY ? Кажется, нет смысла писать класс для выполнения такого рода запросов (с параметрами конструктора или сеттерами для таблицы, столбца, связанных переменных и т. Д.), А затем повторное использование его во всем приложении. Но в то же время я не могу поколебать это ворчащее чувство, что я повторяюсь.

Может быть, просто так много способов написать простой запрос и что такого количества повторений, как это, следует ожидать.

Мысли?

ответ

1

Многие люди делают именно это. Создайте класс, представляющий каждую таблицу, все наследуемые от одного класса. Базовый класс может обрабатывать и сохранять данные. Поэтому, если вы хотите загрузить данные, вы просто вызываете метод загрузки. И вы можете установить и получить доступ к значениям полей по свойствам объектов.

Есть также библиотеки, такие как hibernate, которые обрабатывают много грязной работы для вас.

+0

@Kibbee - Спасибо. Я не буду использовать Hibernate, но я создал класс ActiveRecord, а затем выложил несколько классов для определенных таблиц. – PartialOrder

1

Я бы сказал, что это было нарушением. С первого взгляда на ваш код (если я чего-то не хватает) эти два утверждения идентичны, за исключением строк «foo» и «bar» (повторяется несколько раз) и вашей фактической бизнес-логики.

Как минимум вы можете извлечь это. Более того, все строки SQL, вероятно, должны быть извлечены. Они всегда казались мне чем-то вроде данных. Если бы у вас был массив строк SQL, таблиц и т. Д., Что бы сделать рефакторинг более очевидным?

(Извлечение строки и другие данные из вашего кода является отличным способом, чтобы начать рефакторинг)

Одним из возможных вариантов, если у вас объект, который имел название таблицы и способ, содержащий бизнес-логику, можно передать он в «Процессор» со всем шаблоном (который является всем остальным кодом, который у вас есть).

Я думаю, что это может сделать его сухим.

(PS. Всегда предпочитайте состав по наследству. Там нет никаких преимуществ для использования наследования по классу, который может «запустить» свои объекты)

+0

@ Bill K. Это был близкий звонок, но я пошел с ответом Кибби, потому что он немного ближе к тому, как я на самом деле справился с этим. Ваши комментарии также очень помогли - особенно об извлечении строк в качестве первого шага в рефакторинге. +1 спасибо! – PartialOrder

0

Вы встречая один из первых желаний на модули. :-)

Существует два общих решения. Первый - отвлечь вызов от всех (или большинства) похожих запросов. И снова к другому набору запросов. А потом к другому. И так далее. К сожалению, это приводит к многочисленным блокам, которые делают то же самое: вызывают запрос, проверяют проблемы, собирают результирующий набор, передают его обратно. Это DAL, но только что-то вроде. Он также не масштабируется.

Второе решение - абстрагировать процесс создания запроса и возвращать результат, а затем посмотреть на абстрагирование доступа к данным поверх этого (что в основном означает, что вы создаете что-то, что собирает SQL). Это, скорее всего, станет правильной ORM, а не простой DAL. Гораздо проще это масштабировать.

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