Я видел и работал с большим количеством более старого кода DAO на основе JDBC, который обычно начинается с методов CRUD. Мой вопрос относится конкретно к методам поиска или «искателям». Обычно я обнаруживаю, что DAO начинаются с двух методов:
Чаще всего этих двух средств поиска недостаточно. Обычно я вижу, что класс DAO неоднократно изменялся для добавления таких методов поиска, как следующие:
Что происходит, так это то, что добавляются дополнительные методы, когда необходимо поддерживать новые {условия} или существующие методы модифицируются для добавления новых параметров в качестве флагов для изменения запроса SQL внутри метода для поддержки дополнительных условий.
Это уродливый подход и нарушает принцип открытого-закрытого. Меня всегда раздражало то, что классы DAO постоянно изменяются всякий раз, когда необходимо поддерживать какое-то новое условие поиска. Исследование этого вопроса часто указывает мне на шаблон репозитория и инкапсуляцию условий для извлечения в виде Спецификации или объектов запроса, а затем их передачу в метод поиска. Но это кажется выполнимым только в том случае, если у вас есть коллекция всего набора данных в памяти или если вы используете какой-то ORM (я работаю со старым кодом JDBC)
Я рассмотрел решение, которое лениво загружает весь набор данных, которым DAO управляет как коллекцию в памяти, затем использует шаблон спецификации в качестве запросов для извлечения. Затем я реализую какой-то наблюдатель в коллекции, который просто обновляет базу данных при вызове методов создания, обновления или удаления. Но очевидно, что производительность и масштабируемость существенно страдают.
Есть мысли по этому поводу?
Спасибо за ответы. У меня есть одна мысль - каково ваше мнение об использовании шаблона Command / Policy для инкапсуляции запросов на доступ к данным? Каждая отдельная конкретная команда может представлять определенный вид доступа и может быть передана в Invoker. Я бы получил множество классов Concrete Command, но каждый из них будет ориентирован только на один вид доступа и должен быть очень тестируемым и изолированным.
public abstract class Command{
public execute();
public void setArguments(CommandArguments args){
//store arguments
}
}
//map based structure for storing and returning arguments
public class CommandArguments{
public String getAsString(String key);
public String getAsInt(String key);
//... others
}
//In some business class...
Command command = CommandFactory.create("SearchByName");
CommandArguments args = new CommandArguments();
args.setValue("name", name);
// others
command.setArguments(args);
List list = command.execute();