На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! В разделе обсуждаются следующие темы:
1) Процесс разработки программного обеспечения.
2) Определение требований к программному обеспечению.
3) Составные части и процесс проектирования (см. Шаблоны проектирования).
4) Документирование программного продукта(проекта).
5) Руководство разработкой программного обеспечения.
6) Проектирование пользовательского интерфейса.
7) Контроль версий проекта (см. Управление версиями в Subversion, Стратегии использования svn).
Модераторы: ElcnU
Страницы: (4) [1] 2 3 ... Последняя » все  ( Перейти к последнему сообщению )  
> Наследование vs реализация интерфейса , Что предпочтительнее?
    Возник сейчас занятный спор. Делаем небольшой сайтец, где n-ое количество разнородного контента (новости, фотографии, события и т. п.) должно быть комментируемым. Я предложил все эти сущности произвести от одной базовой (CommentableEntity). Мой напарник предложил отразить это свойство (комментируемость) посредством реализации интерфейса ICommentableEntity, аргументируя, что так правильнее с точки зрения возможного последующего рефакторинга. В любом случае, для отражения всей доменной модели на базу будет использоваться механизмы Entity Framework и как оно там будет "разложено" по таблицам - сейчас не важно. Но вопрос то остался! Видимо, я отстал от последних тенденций в проектировании, и сейчас действительно считается, что наследование следует заменять на реализацию интерфейсов? Кто как думает?
      Интерфейс, если реализация может быть кардинально разной, и ничего общего у разных реализаций нет. Для обслуживания специфических случаев есно сначала общий класс, обслуживающий общий функционал, а специфика - в подклассах.

      Можно ведь ввести и то, и то. А в данном случае по-моему достаточно одного базового класса.
        Цитата Машина @
        Интерфейс, если реализация может быть кардинально разной, и ничего общего у разных реализаций нет.

        Вот тут как раз обратный вариант. Общего то у всех этих сущностей может быть много чего. Из очевидного (как минимум):
        - Дата создания
        - Автор
        - Заголовок
        - Описание
        - Права доступа.

        Ну а дальше - уже специфика. Для новостей - это brief, например. Для событий - место проведение и детальное описание, для фотографий - урлы всякие. Ну и т. д.
          Цитата Flex Ferrum @
          Вот тут как раз обратный вариант. Общего то у всех этих сущностей может быть много чего

          Ага, поэтому общий класс и лучше.

          А то, что напарник хочет, а ты спроси его, чем интерфейс будет лучше с т.з. рефакторинга чем базовый класс? По-моему похоже, что он просто повторяет заслышанное, мол "грамотные прогеры юзают интерфейсы, т.к. это круче для рефакторинга" и хочет насильно сделать все "по книжке", без особо реального понимания, что и зачем. Хотя могу и ошибаться :rolleyes:
            Напарник это я :)

            Давай конкретизируем вопрос. Есть 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 или наоборот. Как-то так.
              Цитата loderan @
              Но нам такая строгость не нужна, нам по сути вполне подойдёт схема многие-к-многим Photos <=> Comments, News <=> Comments, Events <=> Comments, т.к. никто в саму базу со стороны лезть не будет и это не банковская система. В этом случае наследование вообще не нужно. И даже интерфейсы изобретать не нужно. Можно немного улучшить ситуацию если ввести UNIQUE ключи на CommentID в join-табличках Photos_Comments, News_Comments и Events_Comments. Цель не до конца достигнута (комментарий может принадлежать сразу и фотографии и новости), но зато теперь у комментария не может быть несколько фотографий.

              Мне кажется, этого вполне будет достаточно... В любом случае, если отдельная таблица будет представленна отдельным классом, то это будет легче восприниматся и пониматся, чем наследование...
              Кстати, видел как то БД, написаную на сях, вот не помню, названия, там как раз на этом принципе и основано создание таблиц...
              Описываешь таблицу, затем если нужна связь, делаешь сет, ну и собственно потом юзаешь... БД достаточно мощная насколько я помню...
              Во всяком случае, мне не представляется, как можно реализовать это с помощью наследования, да еще при этом просто, и прозрачно...Разве что заюзать какойнить паттерн? :huh:
                loderan, любая модель - искусственная вещь и существует только в наших головах ;)

                Относительно вашей проблемы... вы меня загрузили :)
                  Цитата D_KEY @
                  Относительно вашей проблемы... вы меня загрузили

                  Да я как понял, у них 4 таблицы есть(ну пока 4, для простоты), и вот они хотят организовать как можно проще и гибче это все... При том что некоторые таблицы имеют связь один ко многим...

                  Добавлено
                  О, я вспомнил кажеца, как та БД называлась, vista вроде, Raima
                  Сообщение отредактировано: KILLER -
                    Цитата Flex Ferrum @
                    Вот тут как раз обратный вариант. Общего то у всех этих сущностей может быть много чего. Из очевидного (как минимум):
                    - Дата создания
                    - Автор
                    - Заголовок
                    - Описание
                    - Права доступа.

                    Ну, а мало ли у чего ещё, кроме комментируемых сущностей, может быть дата создания и прав доступа? Я не думаю, что перечисленные поля появляются именно в тот момент, когда мы прикрепляем к чему-то ярлык "можно комментировать". Если убрать у фотографии возможность комментировать, разве у неё исчезнет автор? С точки зрения последующих изменений ваш напарник, imho, прав - мало ли что ещё потом захочется комментировать?
                    Хотя тут, конечно, очень важно то, что язычог то без множественного наследования - именно в этом я вижу проблему, а не в современных тенденциях.
                    Ну, а если предыдущие рассуждения про поля не кажутся убедительными и всё же хочется не дублировать реализацию, то никто же не мешает сделать интерфейс ICommentableEntity, сказать, что класс CommentableEntity его реализует, а от него уже всё отнаследовать.
                      Цитата Машина @
                      повторяет заслышанное, мол "грамотные прогеры юзают интерфейсы, т.к. это круче для рефакторинга" и хочет насильно сделать все "по книжке"


                      Согласен, я книжек много читаю а опыта маловато. Но было несколько проектов (ещё на С++), где я вдумчиво (как мне казалось) наворачивал иерархию классов, которая потом приводила к коллапсу всего проекта, т.к. базнес-модель немного менялась, иерархия переставала отражать объективные вещи и наступало состояние фрустрации. В общем, коллеги, я ваще мнение ценю и прислушиваюсь.
                        Цитата loderan @
                        В данном конкретном случае вот несколько аргументов почему наследование от CommentatableEntity плохо:
                        1. Жесткое ограничение на тип первичного ключа. Нельзя сделать первиичный ключ у Photo - int, у Event - DateTime, а у News - Guid.
                        2. Предположим, что к некоторым этим сущностям (не ко всем, а именно к некотторым) мы захотим привяать, ну, к примеру MiniComments? Придётся делать иерархию. Что-то будет наследоваться от CommentatableEntity, а что-то от EntityWithMiniComments.
                        3. А теперь предположим, что мы вводим AdminComments для другого (пересекающегося) набора сущностей. В этом случае дерево наследования вообще рушится, т.к. структура становится не древовидная, а сетевая. В этом случае приходится вводить какие-то искуственные поля или соглашения, чтобы подогнать ситуацию под имеющийся подход. А это уже не программирование, а сплошной геморрой.

                        Да, в начале я вообще неправильно понял, думал, что говорим про наследование самих комментов, а не комментируемых сущностей :wall:
                        По-моему тогда да, если уж, то интерфейс, а вообще смысл это делать? Это как придумать DeletableEntity и пихать в нее все, что у нас есть. А смысл?

                        Лучше ИМХО сделать структуру классов для каментов, т.е. BaseComment, от нее специфические случаи, а BaseComment привязывать к комментируемым (ну ок, можно наложить интерфейс :rolleyes: ).
                          Цитата loderan @
                          В этом случае согласен, можно сделать наследование. Но при этом назвать базовую сущность не в коем случае не CommentatableEntity. CommentatableEntity - это чисто функциональное понятие, тут должен быть интерфейс. Можно назвать базовую сущность ContentElement, например.

                          Вот, кстати, да, согласен.
                            Цитата Flex Ferrum @
                            n-ое количество разнородного контента (новости, фотографии, события и т. п.) должно быть комментируемым. Я предложил все эти сущности произвести от одной базовой (CommentableEntity).

                            А зачем? Зачем самой сущности знать, что она комментируема(или не комментируема)?
                              Почему теперь две темы с разным количеством ответов? :wacko:

                              Добавлено
                              Тудыть твою... теперь они снова совпадают...
                                Цитата Flex Ferrum @
                                Наследование vs реализация интерфейса

                                А это взаимоисключающие понятия? :)

                                Спор, насколько я понимаю, из-за того наследовать функционал или агреггировать :) Или нет? :)
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0454 ]   [ 17 queries used ]   [ Generated: 5.05.24, 21:36 GMT ]