Залишаючись OO та Testable під час роботи з базою даних


16

Які існують стратегії OOP для роботи з базою даних, але для того, щоб зберігати речі перевіряти? Скажімо, у мене є клас користувача, і моє виробниче середовище працює проти MySQL. Я бачу пару можливих підходів, показаних тут за допомогою PHP:

  1. Передайте джерело $ data_source з інтерфейсами для load() та save(), щоб абстрагувати джерело даних. Під час тестування пройдіть інший сховище даних.

    $ user = новий Користувач ($ mysql_data_source);
    $ user-> load ('bob');
    $ user-> setNickname ('Robby');
    $ user-> save ();
    
  2. Використовуйте фабрику, яка отримує доступ до бази даних і передає результат результату конструктору користувача. Під час тестування вручну генеруйте параметр $ row або знущайтеся над об'єктом у UserFactory :: $ data_source. (Як я можу зберегти зміни до запису?)

    class UserFactory {
        static $data_source;
    
        public static function fetch( $username ) {
            $row = self::$data_source->get( [params] );
    
            $user = new User( $row );
            return $user;
        }
    }
    

У мене поруч є шаблони дизайну та чистий код , але я намагаюся знайти відповідні концепції.


Відповіді:


11

Тож, що ви хочете підібрати, - це моделі Мартіна Фаулерса з архітектури корпоративних застосувань (він також пропонує каталог на своєму веб-сайті тут ).

У ньому він описує кілька моделей абстрагування доступу до даних. Перший описаний вами підхід - Active Record . Ваш другий підхід схожий на табличний шлюз даних .

Ще кращим підходом є використання O / RM для усунення потреби в написанні коду доступу до даних вручну. Я не використовував PHP, оскільки ми турбувалися про Y2K, але у wikipedia є список варіантів для вас . Я не знаю, чи добре вони. Я можу сказати вам, що потрібно шукати в O / RM:

  • Ігнорування стійкості : O / RM не повинен змушувати ваші бізнес-об’єкти виходити з певного інтерфейсу / класу для участі в стратегії доступу до даних.
  • Картографування відносин : ви повинні мати можливість відображати відносини між вашими об'єктами (у клієнта є замовлення, у замовленнях є позиції, у позиціях є товар тощо)
  • Ієрахічне картографування : ви повинні мати можливість відображати ієрархії класів у базі даних.
  • Підтримка синтаксису / критеріїв запитів : Ви повинні мати можливість створити запит під час виконання з точки зору ваших Об'єктів, не з точки зору бази даних, а O / RM повинен перевести та запустити запит у базі даних. Додаткові бали, якщо запит є сильно набраним ланцюжком замість рядка.

Є й інші фактори, які слід враховувати, але це одні з найважливіших. Сподіваюсь, це допомагає.


6

ІМХО, це залежить від того, що ви хочете перевірити, якщо ви хочете перевірити свою логіку бізнесу, вам слід заглушити / знущатися ( Мартін Фаулер ), щоб отримати доступ до даних, щоб ваша перша пропозиція була приємним початком. Це запитання про stackoverflow дає чудовий приклад C # (я намагався знайти кілька зразків PHP, але не зміг знайти жодного).

Якщо ви хочете перевірити доступ до даних сам по собі, це більше не називається тестуванням одиниць, а лише тестуванням інтеграції. Прочитайте тут, щоб отримати загальні вказівки, це питання про stackoverflow також має цікаві посилання.

Якщо ви хочете перевірити логіку збереженої процедури у вашій базі даних, подивіться на xUnit TestPattern

Сподіваюсь, це допомагає


2

Це не обов'язково є негайно корисною відповіддю, але якщо ви дійсно стурбовані перевіреністю баз даних, вам слід розглянути, як це робиться в Ruby on Rails. Наскільки я знаю, ніхто краще чи інтуїтивно не висвітлював цю тему.


2
Ruby on Rails за замовчуванням реалізує шаблон "Активні записи". Можна також надати посилання: en.wikipedia.org/wiki/Active_record_pattern
Spoike

0

Я рекомендував вам перевірити рішення Symfony Framework для подібної проблеми. Symfony має свою рамку php OO з функціональними тестами.

Ось посилання , вони використовували щось на кшталт того, про що ви думаєте.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.