Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.191.102.112] |
|
Страницы: (4) [1] 2 3 ... Последняя » все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Возник сейчас занятный спор. Делаем небольшой сайтец, где n-ое количество разнородного контента (новости, фотографии, события и т. п.) должно быть комментируемым. Я предложил все эти сущности произвести от одной базовой (CommentableEntity). Мой напарник предложил отразить это свойство (комментируемость) посредством реализации интерфейса ICommentableEntity, аргументируя, что так правильнее с точки зрения возможного последующего рефакторинга. В любом случае, для отражения всей доменной модели на базу будет использоваться механизмы Entity Framework и как оно там будет "разложено" по таблицам - сейчас не важно. Но вопрос то остался! Видимо, я отстал от последних тенденций в проектировании, и сейчас действительно считается, что наследование следует заменять на реализацию интерфейсов? Кто как думает?
|
Сообщ.
#2
,
|
|
|
Интерфейс, если реализация может быть кардинально разной, и ничего общего у разных реализаций нет. Для обслуживания специфических случаев есно сначала общий класс, обслуживающий общий функционал, а специфика - в подклассах.
Можно ведь ввести и то, и то. А в данном случае по-моему достаточно одного базового класса. |
Сообщ.
#3
,
|
|
|
Цитата Машина @ Интерфейс, если реализация может быть кардинально разной, и ничего общего у разных реализаций нет. Вот тут как раз обратный вариант. Общего то у всех этих сущностей может быть много чего. Из очевидного (как минимум): - Дата создания - Автор - Заголовок - Описание - Права доступа. Ну а дальше - уже специфика. Для новостей - это brief, например. Для событий - место проведение и детальное описание, для фотографий - урлы всякие. Ну и т. д. |
Сообщ.
#4
,
|
|
|
Цитата Flex Ferrum @ Вот тут как раз обратный вариант. Общего то у всех этих сущностей может быть много чего Ага, поэтому общий класс и лучше. А то, что напарник хочет, а ты спроси его, чем интерфейс будет лучше с т.з. рефакторинга чем базовый класс? По-моему похоже, что он просто повторяет заслышанное, мол "грамотные прогеры юзают интерфейсы, т.к. это круче для рефакторинга" и хочет насильно сделать все "по книжке", без особо реального понимания, что и зачем. Хотя могу и ошибаться |
Сообщ.
#5
,
|
|
|
Напарник это я
Давай конкретизируем вопрос. Есть 4 сущности: Photo, News, Event и Comment. Для каждой фотографии, новости или события может быть несколько (0..много) комментариев. Каждый комментарий может принадлежать только одной сущности. Строго говоря, если задаться целью сделать контроль этих зависимостей на уровне SQL-базы, ничего другого в голову не приходит, как населдовать Photo, News и Event от базовой сущности CommentatableEntity, в которой определён общий сквозной ключ CommentatableEntityID. Но нам такая строгость не нужна, нам по сути вполне подойдёт схема многие-к-многим Photos <=> Comments, News <=> Comments, Events <=> Comments, т.к. никто в саму базу со стороны лезть не будет и это не банковская система. В этом случае наследование вообще не нужно. И даже интерфейсы изобретать не нужно. Можно немного улучшить ситуацию если ввести UNIQUE ключи на CommentID в join-табличках Photos_Comments, News_Comments и Events_Comments. Цель не до конца достигнута (комментарий может принадлежать сразу и фотографии и новости), но зато теперь у комментария не может быть несколько фотографий. Лично я считаю, что наследование это всегда очень серьзное ограничение на структуру модели. И по возможности нужно от наследования избавляться в пользу интерфейсов. В данном конкретном случае вот несколько аргументов почему наследование от CommentatableEntity плохо: 1. Жесткое ограничение на тип первичного ключа. Нельзя сделать первиичный ключ у Photo - int, у Event - DateTime, а у News - Guid. 2. Предположим, что к некоторым этим сущностям (не ко всем, а именно к некотторым) мы захотим привяать, ну, к примеру MiniComments? Придётся делать иерархию. Что-то будет наследоваться от CommentatableEntity, а что-то от EntityWithMiniComments. 3. А теперь предположим, что мы вводим AdminComments для другого (пересекающегося) набора сущностей. В этом случае дерево наследования вообще рушится, т.к. структура становится не древовидная, а сетевая. В этом случае приходится вводить какие-то искуственные поля или соглашения, чтобы подогнать ситуацию под имеющийся подход. А это уже не программирование, а сплошной геморрой. В общем, моё мнение, что наследование - это очень искуственное понятие, существующее только в головах людей. В жизни бывают разные отношения между объектами. Объект может на какое-то время я кому-то показаться частным случаем другого объекта. Кому-то другому может показаться что-то совершенно другое, если у него другой в этот момент взгляд на вещи. Ну, и если уж пошла такая философия, то и реляционная модель это очень искуственная вещь. Но это уже отдельная тема для разговора. Добавлено Цитата Flex Ferrum @ Вот тут как раз обратный вариант. Общего то у всех этих сущностей может быть много чего. В этом случае согласен, можно сделать наследование. Но при этом назвать базовую сущность не в коем случае не CommentatableEntity. CommentatableEntity - это чисто функциональное понятие, тут должен быть интерфейс. Можно назвать базовую сущность ContentElement, например. Тогда у меня возражений нет. Но если базовый класс называется CommentatableEntity то у меня возникает диссонанс. Это то же самое, что наследовать от класса SortableCollection. А потом думать ReversableCollection наследуется от SortableCollection или наоборот. Как-то так. |
Сообщ.
#6
,
|
|
|
Цитата loderan @ Но нам такая строгость не нужна, нам по сути вполне подойдёт схема многие-к-многим Photos <=> Comments, News <=> Comments, Events <=> Comments, т.к. никто в саму базу со стороны лезть не будет и это не банковская система. В этом случае наследование вообще не нужно. И даже интерфейсы изобретать не нужно. Можно немного улучшить ситуацию если ввести UNIQUE ключи на CommentID в join-табличках Photos_Comments, News_Comments и Events_Comments. Цель не до конца достигнута (комментарий может принадлежать сразу и фотографии и новости), но зато теперь у комментария не может быть несколько фотографий. Мне кажется, этого вполне будет достаточно... В любом случае, если отдельная таблица будет представленна отдельным классом, то это будет легче восприниматся и пониматся, чем наследование... Кстати, видел как то БД, написаную на сях, вот не помню, названия, там как раз на этом принципе и основано создание таблиц... Описываешь таблицу, затем если нужна связь, делаешь сет, ну и собственно потом юзаешь... БД достаточно мощная насколько я помню... Во всяком случае, мне не представляется, как можно реализовать это с помощью наследования, да еще при этом просто, и прозрачно...Разве что заюзать какойнить паттерн? |
Сообщ.
#7
,
|
|
|
loderan, любая модель - искусственная вещь и существует только в наших головах
Относительно вашей проблемы... вы меня загрузили |
Сообщ.
#8
,
|
|
|
Цитата D_KEY @ Относительно вашей проблемы... вы меня загрузили Да я как понял, у них 4 таблицы есть(ну пока 4, для простоты), и вот они хотят организовать как можно проще и гибче это все... При том что некоторые таблицы имеют связь один ко многим... Добавлено О, я вспомнил кажеца, как та БД называлась, vista вроде, Raima |
Сообщ.
#9
,
|
|
|
Цитата Flex Ferrum @ Вот тут как раз обратный вариант. Общего то у всех этих сущностей может быть много чего. Из очевидного (как минимум): - Дата создания - Автор - Заголовок - Описание - Права доступа. Ну, а мало ли у чего ещё, кроме комментируемых сущностей, может быть дата создания и прав доступа? Я не думаю, что перечисленные поля появляются именно в тот момент, когда мы прикрепляем к чему-то ярлык "можно комментировать". Если убрать у фотографии возможность комментировать, разве у неё исчезнет автор? С точки зрения последующих изменений ваш напарник, imho, прав - мало ли что ещё потом захочется комментировать? Хотя тут, конечно, очень важно то, что язычог то без множественного наследования - именно в этом я вижу проблему, а не в современных тенденциях. Ну, а если предыдущие рассуждения про поля не кажутся убедительными и всё же хочется не дублировать реализацию, то никто же не мешает сделать интерфейс ICommentableEntity, сказать, что класс CommentableEntity его реализует, а от него уже всё отнаследовать. |
Сообщ.
#10
,
|
|
|
Цитата Машина @ повторяет заслышанное, мол "грамотные прогеры юзают интерфейсы, т.к. это круче для рефакторинга" и хочет насильно сделать все "по книжке" Согласен, я книжек много читаю а опыта маловато. Но было несколько проектов (ещё на С++), где я вдумчиво (как мне казалось) наворачивал иерархию классов, которая потом приводила к коллапсу всего проекта, т.к. базнес-модель немного менялась, иерархия переставала отражать объективные вещи и наступало состояние фрустрации. В общем, коллеги, я ваще мнение ценю и прислушиваюсь. |
Сообщ.
#11
,
|
|
|
Цитата loderan @ В данном конкретном случае вот несколько аргументов почему наследование от CommentatableEntity плохо: 1. Жесткое ограничение на тип первичного ключа. Нельзя сделать первиичный ключ у Photo - int, у Event - DateTime, а у News - Guid. 2. Предположим, что к некоторым этим сущностям (не ко всем, а именно к некотторым) мы захотим привяать, ну, к примеру MiniComments? Придётся делать иерархию. Что-то будет наследоваться от CommentatableEntity, а что-то от EntityWithMiniComments. 3. А теперь предположим, что мы вводим AdminComments для другого (пересекающегося) набора сущностей. В этом случае дерево наследования вообще рушится, т.к. структура становится не древовидная, а сетевая. В этом случае приходится вводить какие-то искуственные поля или соглашения, чтобы подогнать ситуацию под имеющийся подход. А это уже не программирование, а сплошной геморрой. Да, в начале я вообще неправильно понял, думал, что говорим про наследование самих комментов, а не комментируемых сущностей По-моему тогда да, если уж, то интерфейс, а вообще смысл это делать? Это как придумать DeletableEntity и пихать в нее все, что у нас есть. А смысл? Лучше ИМХО сделать структуру классов для каментов, т.е. BaseComment, от нее специфические случаи, а BaseComment привязывать к комментируемым (ну ок, можно наложить интерфейс ). |
Сообщ.
#12
,
|
|
|
Цитата loderan @ В этом случае согласен, можно сделать наследование. Но при этом назвать базовую сущность не в коем случае не CommentatableEntity. CommentatableEntity - это чисто функциональное понятие, тут должен быть интерфейс. Можно назвать базовую сущность ContentElement, например. Вот, кстати, да, согласен. |
Сообщ.
#13
,
|
|
|
Цитата Flex Ferrum @ n-ое количество разнородного контента (новости, фотографии, события и т. п.) должно быть комментируемым. Я предложил все эти сущности произвести от одной базовой (CommentableEntity). А зачем? Зачем самой сущности знать, что она комментируема(или не комментируема)? |
Сообщ.
#14
,
|
|
|
Почему теперь две темы с разным количеством ответов?
Добавлено Тудыть твою... теперь они снова совпадают... |
Сообщ.
#15
,
|
|
|
Цитата Flex Ferrum @ Наследование vs реализация интерфейса А это взаимоисключающие понятия? Спор, насколько я понимаю, из-за того наследовать функционал или агреггировать Или нет? |