Я видел и работал со многими более старыми, основанными на JDBC кодами DAO, которые обычно начинаются с методов CRUD.Мой вопрос относится конкретно к поисковым методам, или «искателям».Обычно я обнаруживаю, что DAO начинаются с двух методов:
- найти и вернуть ALL
- для извлечения конкретного экземпляра на основе уникального идентификатора
Чаще всего этих двух искателей недостаточно.Я обычно заканчиваю тем, что вижу класс DAO, неоднократно модифицированный для добавления методов поиска, подобных следующему:
- найти и вернуть ВСЕ, где {условие}
Что происходит, когда больше методовдобавляются, когда необходимо поддерживать новые {условия} или когда существующие методы модифицируются для добавления новых параметров в качестве флагов для изменения SQL-запроса внутри метода для поддержки дополнительных условий.
Это уродливый подход и нарушаетОткрытый Закрытый Принцип.Я всегда был в восторге от того, что классы DAO постоянно модифицируются всякий раз, когда необходимо поддерживать какое-то новое условие поиска.Исследования по этому вопросу часто указывают на шаблон репозитория и инкапсулируют условия для извлечения в виде Спецификации или объектов Query, а затем передают их в метод поиска.Но это кажется возможным только в том случае, если у вас есть коллекция всего набора данных в памяти или если вы используете какой-то ORM (я работаю со старым кодом JDBC)
Я рассмотрел решение, котороеЛенивый загружает весь набор данных, который DAO управляет как коллекция в памяти, а затем использует шаблон спецификации в качестве запросов для извлечения.Затем я внедряю в коллекцию своего рода наблюдателя, который просто обновляет базу данных при вызове методов создания, обновления или удаления.Но очевидно, что производительность и масштабируемость значительно страдают.
Есть мысли по этому поводу?
Спасибо за ответы до сих пор.У меня есть одна мысль - что вы думаете об использовании шаблона Command / Policy для инкапсуляции запросов на доступ к данным?Каждая отдельная конкретная команда может представлять определенный вид доступа и может быть передана в Invoker.Я бы закончил с многочисленными классами Concrete Command, но каждый из них будет ориентирован только на один вид доступа и должен быть очень тестируемым и изолированным.
public abstract class Command<R>{
public <R> 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<Customer> list = command.execute();