Это не «переставлять» двигатель. Это значит: к одному двигателю прицепить все машины в мире.
Абсолютно верно.
Все дружно поедут?
А вот это уже зависит от реализации. В реальном мире один мотор засунуть в несколько машин не получится, потому что машины не сделаны потокобезопасными. :) А в мире программирования не только получится, но даже иногда и приходится. Да хранят нас средства синхронизации!
Эта статья посвящена созданию модели данных, которая красиво ложилась бы на SQL и содержала в себе «правильное» ООП наследование.
Потом перечислены четыре подхода, как это делалось, со словами «плюс данного подхода» и «минус данного подхода». Последний (мой собственный) подход сравнивается с остальными (более общепринятыми).
Заключение:
Понятно, что предложенный подход ни разу не является «золотой пулей». Тем более при том, что метод «по умолчанию» отрабатывает настолько хорошо. Но я думаю, что он может-таки кому-нибудь пригодиться в каких-либо специфических обстоятельствах.
Одна задача, разные способы, сравнение. Что ещё надо? Ах да, флейм впустую развести забыл! Ан нет, всё нормально, комментаторы за меня справятся.
а давало ли какие-либо преимущества натягивание ООП модели на реляционную БД?
Проект представлял из себя многокомпонентную систему, в которой доступ к данным быстро и без головной боли делался с помощью Entity Framework («быстро» было очень важно). Всех всё устраивало. Так как с самого начала было понятно, что разработка и сопровождение растянутся на 5+ лет, то структуру данных решено было делать максимально простой и прозрачной, чтобы уменьшить головную боль себе и коллегам, которые приступят к доработке спустя пару лет. То есть, максимально использовать принцип KISS, в том числе и заставить таблицы в БД соответствовать классам уровней бизнес-логики (их было 3, если я ничего не путаю).
хочу узнать каков профит получился.
Одни люди смогли быстро разработать и внедрить первую очередь продукта, а другие спустя пару лет не проклинали первых, когда сели за дальнейшую доработку проекта.
тенденции вроде активно призывают минимизировать наследование
Наследование — не более чем инструмент. Есть места, где он уместен, и есть, где он выглядит как седло на корове. Естественно, не все проекты, над которыми я работал, активно использовали наследование. Если сейчас в силу каких-либо новшеств становится всё больше проектов, где наследование скорее вредит, то вполне естественно, что его будут использовать меньше. И я его не буду пихать куда угодно просто в силу какой-то извращённой любви. Если я шутки ради (ну и в качестве курсового проекта, чего греха таить) написал (сильно упрощая) полиморфный вирус на T-SQL, это ни разу не означает, что T-SQL — это идеальный язык для написания полиморфных вирусов. Каждому инструменту — своё место на полке.
Попробую ответить покороче. Эта статья есть суммирование тех подходов, которые использовались для максимально близкого и простого сопряжения ООП, EF и SQL на примерно пяти совершенно разных проектах, разрабатывавшихся разными командами на протяжении примерно десяти лет. И требования там тоже разные были. И DTO был, и без него тоже обходились. Другими словами, я рассказал про цвета и формы ручек молотков, которыми мы забивали гвозди, (и, чего греха таить, иногда даже шурупы с болтами). И я очень не хочу спорить на тему того, что десять лет назад мне нужно было всё это делать отвёрткой, включая забивание гвоздей и закручивание гаек.
М-м-м, чем пахнет? По-моему, священной войной. Структура таблиц в БД может как соответствовать структуре классов на одном из уровней, так и не соответствовать. Я подчёркиваю: в статье я перечислил подходы, с помощью которых одно умышленно пыталось быть приведённым в соответствие со вторым в разных проектах (и разных организациях) на протяжении 10 лет. Причин так делать тоже было много и разных, в том числе навязанных дядьками предпенсионного возраста с другой половины глобуса.
Ну и да, теперь у вас две параллельных структуры классов (для хранения и для бизнес-логики). Что у них с областями видимости и применения?
Я наблюдал и больше, чем две параллельные структуры для одного и того же набора сущностей одновременно. Всё определяется требованиями.
Я имею в виду, что структура классов должна более-менее соответствовать структуре таблиц, и всё это должно подчиняться логике ООП. А не «всё в одной таблице», как в варианте classification.
Дайте я угадаю, вы используете model-first, не code-first?
Да, в 4-х enterprise-проектах с Entity Framework использовался именно model-first.
Зачем вам в этой схеме дискриминатор? А без дискриминатора это та же первая схема, только с нормальными именами таблиц, и называется это table-per-type.
И уж точно нет никакого смысла делать дискриминатор отдельной таблицей.
Поясню:
1) Совсем без дискриминатора делать не вариант, потому что иногда приходится читать просто таблицу A. А как узнать «класс» записей в ней без дополнительных join-ов?
2) Дискриминатор и триггеры позволяют избежать ситуации, когда одной записи в таблице А соответствуют записи сразу в нескольких дочерних таблицах (например, B, C и F). Это вполне может быть некоторым оригинальным архитектурным решением, но с точки зрения ООП такая ситуация является ошибкой (если быть более точным, то это подмена наследования композицией).
3) В большом проекте отдельная таблица дискриминатора может использоваться для тестов. Пример из реального проекта: тест проверял, чтобы всем классам из структуры были проставлены корректные атрибуты (DataContact, использовавшийся WCF, и прочие, поддерживавшие инфраструктуру), перечисление (ClassEnum в тексте статьи) содержало все необходимые значения из базы и наоборот, а таблицы в БД соответствовали классам уровня Business Logic.
А вот это уже зависит от реализации. В реальном мире один мотор засунуть в несколько машин не получится, потому что машины не сделаны потокобезопасными. :) А в мире программирования не только получится, но даже иногда и приходится. Да хранят нас средства синхронизации!
Потом перечислены четыре подхода, как это делалось, со словами «плюс данного подхода» и «минус данного подхода». Последний (мой собственный) подход сравнивается с остальными (более общепринятыми).
Заключение:
Одна задача, разные способы, сравнение. Что ещё надо? Ах да, флейм впустую развести забыл! Ан нет, всё нормально, комментаторы за меня справятся.
Проект представлял из себя многокомпонентную систему, в которой доступ к данным быстро и без головной боли делался с помощью Entity Framework («быстро» было очень важно). Всех всё устраивало. Так как с самого начала было понятно, что разработка и сопровождение растянутся на 5+ лет, то структуру данных решено было делать максимально простой и прозрачной, чтобы уменьшить головную боль себе и коллегам, которые приступят к доработке спустя пару лет. То есть, максимально использовать принцип KISS, в том числе и заставить таблицы в БД соответствовать классам уровней бизнес-логики (их было 3, если я ничего не путаю).
Одни люди смогли быстро разработать и внедрить первую очередь продукта, а другие спустя пару лет не проклинали первых, когда сели за дальнейшую доработку проекта.
Наследование — не более чем инструмент. Есть места, где он уместен, и есть, где он выглядит как седло на корове. Естественно, не все проекты, над которыми я работал, активно использовали наследование. Если сейчас в силу каких-либо новшеств становится всё больше проектов, где наследование скорее вредит, то вполне естественно, что его будут использовать меньше. И я его не буду пихать куда угодно просто в силу какой-то извращённой любви. Если я шутки ради (ну и в качестве курсового проекта, чего греха таить) написал (сильно упрощая) полиморфный вирус на T-SQL, это ни разу не означает, что T-SQL — это идеальный язык для написания полиморфных вирусов. Каждому инструменту — своё место на полке.
Я наблюдал и больше, чем две параллельные структуры для одного и того же набора сущностей одновременно. Всё определяется требованиями.
Да, в 4-х enterprise-проектах с Entity Framework использовался именно model-first.
Поясню:
1) Совсем без дискриминатора делать не вариант, потому что иногда приходится читать просто таблицу A. А как узнать «класс» записей в ней без дополнительных join-ов?
2) Дискриминатор и триггеры позволяют избежать ситуации, когда одной записи в таблице А соответствуют записи сразу в нескольких дочерних таблицах (например, B, C и F). Это вполне может быть некоторым оригинальным архитектурным решением, но с точки зрения ООП такая ситуация является ошибкой (если быть более точным, то это подмена наследования композицией).
3) В большом проекте отдельная таблица дискриминатора может использоваться для тестов. Пример из реального проекта: тест проверял, чтобы всем классам из структуры были проставлены корректные атрибуты (DataContact, использовавшийся WCF, и прочие, поддерживавшие инфраструктуру), перечисление (ClassEnum в тексте статьи) содержало все необходимые значения из базы и наоборот, а таблицы в БД соответствовали классам уровня Business Logic.