Использование статических методов для взаимодействия с базой данных - есть ли потенциальные проблемы?

Я смотрю на класс, обрабатывающий доступ к базе данных для приложения MVC3 / .Net.

Этот класс является статическим и предоставляет удобные удобные методы для обычных запросов к БД - всевозможные хитрые вещи, такие как GetColumnBValueForColumnA (), а также гораздо более сложные запросы. Он хорошо разложен / оптимизирован для данного решения и предметной области.

Однако видение класса статическим вызвало некоторую полузабытую память о том, что это может быть плохой идеей (может быть, в контексте многопоточности?), И я не могу избавиться от этого чувства.

Это хорошая идея, чтобы этот класс оставался статичным, или я должен создавать его экземпляр для каждого вызова базы данных?


person blueberryfields    schedule 23.01.2012    source источник
comment
Это очень часто встречается в паттерне Active Record ... В этом нет ничего плохого!   -  person Mike Christensen    schedule 24.01.2012
comment
есть ли статическое состояние? предназначен ли он для реализации какой-либо абстракции (интерфейса и т. д.)?   -  person Marc Gravell    schedule 24.01.2012
comment
@MarcGravell Эти классы не содержат статического состояния. В какой-то момент они создают оболочку вокруг соединения с базой данных в качестве помощника для построения соответствующих запросов.   -  person blueberryfields    schedule 24.01.2012
comment
@blueberryfields и откуда они берут базовое соединение с базой данных, если не из статического состояния? Вы передаете соединение в качестве параметра?   -  person CodesInChaos    schedule 24.01.2012
comment
Я все еще схожу с ума по этому коду. Похоже, что оболочка создается (и создает соединение с БД) для каждого запроса   -  person blueberryfields    schedule 24.01.2012


Ответы (2)


Это хорошая идея, чтобы этот класс оставался статичным, или я должен создавать его экземпляр для каждого вызова базы данных?

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

Если вас не волнуют эти вещи, тогда подойдут статические методы. Единственное, что нужно соблюдать при работе со статическими методами, - это проектировать их так, чтобы они были реентерабельными и не зависят от какого-либо общего состояния, чтобы быть потокобезопасным. Во всех случаях убедитесь, что вы правильно удалили все ресурсы IDisposable, такие как соединения и команды с базой данных, заключив их в инструкции using.

person Darin Dimitrov    schedule 23.01.2012
comment
работа с абстракциями носит общий характер - что вы имеете в виду, когда говорите это? - person blueberryfields; 24.01.2012
comment
@blueberryfields, конкретно абстракции в .NET - это либо интерфейсы, либо абстрактные классы. Таким образом, в основном ваше действие контроллера должно принимать интерфейс или абстрактный класс в качестве аргумента конструктора, который будет определять контракт всех операций, которые вы хотите выполнить. Затем вы должны настроить свой любимый инструмент внедрения зависимостей, чтобы внедрить конкретную реализацию этого репозитория или контракта доступа к данным в контроллер. Теперь мы говорим о слабой связи между вашим контроллером и уровнем доступа к данным в рамках этого контракта. - person Darin Dimitrov; 24.01.2012

Это хорошая идея, чтобы этот класс оставался статичным, или я должен создавать его экземпляр для каждого вызова базы данных?

Это не единственные два варианта.

Класс не должен не быть статическим: сделав его статическим , вы откажетесь от нескольких важных преимуществ объекта -ориентированное программирование, при этом практически ничего не получая.

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

Вот пара преимуществ:

  1. Допустим, вы хотите провести модульное тестирование метода, основанного на этом классе доступа к данным. Если вы используете внедренный интерфейс службы, а не вызываете статический метод напрямую, вы можете создать объект Mock, указать ему, как себя вести, и позволить методу, который вы тестируете, думать, что он становится реальным. data, когда на самом деле вы просто скармливаете ему данные, которые хотите проверить.
  2. Допустим, вы в конечном итоге захотите кэшировать результаты ваших вызовов доступа к данным. Вы можете внедрить класс кэширования, который обертывает реальный класс, возвращая кешированные результаты, где это возможно, и вызывая реальные методы доступа к данным, когда кешированные значения отсутствуют. Ничего из этого не потребует каких-либо изменений в вашем классе доступа к данным.

Я мог бы продолжить. Статические классы убивают вашу гибкость и не имеют практического преимущества в 99% случаев.

person StriplingWarrior    schedule 23.01.2012