На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
! Правила раздела:
1. Название темы - краткое описание кто/что против кого/чего
2. В первом сообщении - список параметров, по которым идет сравнение.
3. Старайтесь аргументировать свои высказывания. Фразы типа "Венда/Слюникс - ацтой" считаются флудом.
4. Давайте жить дружно и не доводить обсуждение до маразма и личных оскорблений.
Модераторы: Модераторы, Комодераторы
Страницы: (8) 1 [2] 3 4 ...  7 8 все  ( Перейти к последнему сообщению )  
> Инкапсуляция vs Агрегирование, размышления в различных реализациях (языках программирования)
   
Что считаете лучшим?
Гости не могут просматривать результаты голосования.
Гости не могут голосовать 
    Цитата Wound @
    Это вроде как ортогональные вещи, как их сравнивать

    Да, ошибся таки, согласен. Давай тогда наследование vs агрегирование?
    Мои программные ништякиhttp://majestio.info
      Цитата JoeUser @
      Да, ошибся таки, согласен. Давай тогда наследование и агрегирование?

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

      Например ты пишешь класс машина. Машина имеет двигатель, соответственно связь будет выражаться отношением Car has engine, Has A - это у нас либо композиция, либо агрегирование. Агрегирование - это когда двигатель будет передаваться через конструктор. Композиция - это когда двигатель будет создаваться в том же классе, где и объявлен(соответственно уничтожиться вместе с классом). Выбирай любую модель, нужную для твоей системы. Ну в смысле как ты спроектировал и что в твоем случае проще юзать.

      Теперь про наследование. Представь что машина у тебя уже есть, а пользователи жалуются, мол де руль тугой. Нужно много сил прикладывать, чтоб повернуть. В итоге тебе нужно выпустить новую машину, но с некоторыми примочками. По сути у тебя это выражается связью A is B, но с примочками.
      A is B - это наследование.
      Соответственно делаешь класс, наследуешь от нужного, и прикручиваешь ему гидроусилитель руля. Вуаля. Теперь у тебя новая машина, с теми же характеристиками, что и старая, но с гидроусилителем.

      В общем я думаю тут холивара не получится. Упрется в то, кто как понимает сущности и какие связи и отношения выстраивает между ними.
        Скрытый текст
        Киля, спасибо!!! Ты бываешь чрезвычайно полезен, когда вещаешь по тематике :good:
        Мои программные ништякиhttp://majestio.info
          Цитата Qraizer @
          Инкапсуляция подразумевает объединение данных и методик их обработки в единой неделимой сущности. Сокрытие тут как приятный бонус, способствующий охране инвариантов этой сущности, и которое в общем-то важнее инкапсуляции как таковой. Агрегирование представляет собой рассмотрение готовой сущности как части другой. Несложно представить некую систему, где сокрытие её агрегатов (возможно, только лишь некоторых) нафик не упёрлось и потому к применению не обязательно. Важно, что агрегирование предоставляет лёгкое повторное использование существующего в контексте другой, более ёмкой, задачи.
          В общем-то я тоже не вполне понимаю, как их сравнивать.

          Добавлено 16 октября, 21:23
          Не, ну можно, конечно, вспомнить всякое там PImpl и вынести все данные в агрегат. Тогда противопоставить одно другому можно. Но это ведь по-любому будет лишь частный случай использования того и другого. В общем же случае критериев сравнения у них как бы и нет, задачи-то они призваны решать разные.

          Qraizer, я не знаю на сколько ты знаком с идеологией Rust'а ... Но если как-то интересовался, "ознакамливался", распиши свой взгляд:
          1) Почему они (создатели раста) решили не реализовать наследование? Заменили его агрегацией?
          2) Почему они (создатели раста) решили инкапсуляцию не реализовывать, а заменили ее типа "иплементацией", считай почти интерфейсами (тут если я не путаю)?
          Мои программные ништякиhttp://majestio.info
            Та откуда ж я знаю. У них спрашивать надо. Когда Страуструпа задолбали подобные вопросы, он аж книжку выпустил с ответами на них. Мож и они сподобятся.
            1. Формально – а зачем наследование вообще нужно? Вот просто если разобраться, что в нём хорошего? Сильные связи между предком и всеми его наследниками проводят к тому, что чуть что где в предке дёрнул, и наследники оказываются в опасности из-за зависимостей от него. Толку от наследования чуть: мол, имеем готовый функционал, который лёгким движением руки воспроизводим в новой ипостаси. Ну так это можно и иначе сделать. Если разобраться, наследование нужно только лишь для построения иерархий, ежели вдруг приспичит. Скажем, в языках со статической типизацией это единственный способ удобно и надёжно реализовать полиморфизм.
              С другой стороны, наследованию, хорошо зная его механизмы, можно то там, то сям найти адекватное применение. Ну, как бы проще будет именно наследованием, чем другими механизмами. И тогда возникает другой вопрос: что делать с множественным наследованием? Конечно, ты в курсе о том, как об этом отзываются апологеты языков, где его нет. Мол, оно не нужно, у нас есть агрегация вместо этого. Почему-то никто из них не может внятно ответить на встречный вопрос: если вам не нужно множественное наследование, потому что есть агрегация, то почему, коли у вас есть агрегация, вам тем не менее нужно простое наследование? Возможно растовщики ровно так и подумали.
            2. Потому что ИМХО инкапсуляция – это сахар. Просто удобно, когда всё в одном месте. На самом деле люди её используются не ради неё, а ради выгод от неё. (Собственно, это справедливо для любой технологии.) Если её можно заменить на что-то иное, дающее те же выгоды, то почему бы и нет. Почему растовщики решили так, как решили, если не "почему бы и нет", то я не знаю.
            Одни с годами умнеют, другие становятся старше.
              Цитата Wound @
              Теперь про наследование. Представь что машина у тебя уже есть, а пользователи жалуются, мол де руль тугой. Нужно много сил прикладывать, чтоб повернуть. В итоге тебе нужно выпустить новую машину, но с некоторыми примочками. По сути у тебя это выражается связью A is B, но с примочками.
              A is B - это наследование.
              Соответственно делаешь класс, наследуешь от нужного, и прикручиваешь ему гидроусилитель руля. Вуаля. Теперь у тебя новая машина, с теми же характеристиками, что и старая, но с гидроусилителем.

              Наследование так не работает. Потому что вам нужно ещё переписать водителя. Но я не об этом.

              Если у нас A1->A2>A3 и вам нужно добавить методы к A3 которые должны получать события от A1 но они там не заложены. Вам нужно будет заменить A1 на B1 и A3 на B3. Поэтому вам нужно всё это протащить через A2. Но что-бы клиенты его не сдохли.

              Поэтому проще наследования, реализовать через композицию что в Rust и сделали.
              А вот сахар в виде иплементации в руст тут трудно судить.
              Правильный обед должен состоять из 5 блюд приготовленных из 33 ингредиентов.
                Скрытый текст
                Qraizer,+1!
                Мои программные ништякиhttp://majestio.info
                  Цитата JoeUser @
                  2) Почему они (создатели раста) решили инкапсуляцию не реализовывать, а заменили ее типа "иплементацией", считай почти интерфейсами (тут если я не путаю)?

                  Зачем эту глупость писать? Оператор точка не является инкапсуляцией как и оператор выбора "|" не является "иплементацией".
                  Правильный обед должен состоять из 5 блюд приготовленных из 33 ингредиентов.
                    Цитата Pavia @
                    Зачем эту глупость писать? Оператор точка не является инкапсуляцией как и оператор выбора "|" не является "иплементацией".

                    ниче не понял :blink:
                    Мои программные ништякиhttp://majestio.info
                      Цитата Pavia @
                      Наследование так не работает. Потому что вам нужно ещё переписать водителя. Но я не об этом.

                      А как работает наследование? У вас какое то свое понимание наследования?
                      Зачем переписывать водителя? Вы когда садитесь за машину с гидроусилителем руля, переучиваетесь на вождение с гидроусилителем? Т.е. водитель, скажем, ЗИЛ, без гидроусилителя, не сможет сесть и поехать на камазе с гидроусилителем? Что за глупости, не понимаю. :-?

                      Цитата Pavia @
                      Если у нас A1->A2>A3 и вам нужно добавить методы к A3 которые должны получать события от A1 но они там не заложены. Вам нужно будет заменить A1 на B1 и A3 на B3. Поэтому вам нужно всё это протащить через A2. Но что-бы клиенты его не сдохли.

                      :wacko:

                      Добавлено
                      Цитата Qraizer @
                      Почему-то никто из них не может внятно ответить на встречный вопрос: если вам не нужно множественное наследование, потому что есть агрегация, то почему, коли у вас есть агрегация, вам тем не менее нужно простое наследование?

                      Чтоб выразить связь A is B. Возьми тот же ГУЙ, как его без наследования нормально писать? Возьми какие нибудь игры, наследованием проще выстраивать иерархии объектов. Ведь проще создать потомка, и вызвать у него нужный метод, чем через объекты вызывать цепочку адского треша.

                      Например я создал некий объект, и у меня перед глазами все методы, которые я могу дергать. А с агрегированием как быть?

                      Добавлено
                      Что до множественного наследования, например в том же C# множественное наследование классов запрещено, для интерфейсов разрешено. И проблема ромба не возникает.
                      Сообщение отредактировано: Wound -
                        Цитата Wound @
                        Возьми тот же ГУЙ, как его без наследования нормально писать?

                        Запросто. Непонятно, зачем его с наследованием писать.

                        Цитата Wound @
                        Ведь проще создать потомка, и вызвать у него нужный метод, чем через объекты вызывать цепочку адского треша.

                        А ещё проще глобальную переменную заюзать и дёргать её откуда угодно.

                        Цитата Wound @
                        Например я создал некий объект, и у меня перед глазами все методы, которые я могу дергать. А с агрегированием как быть?

                        Так же. Создать объект и посмотреть глазами все методы, которые ты можешь дёргать.

                        Цитата Wound @
                        Что до множественного наследования, например в том же C# множественное наследование классов запрещено, для интерфейсов разрешено. И проблема ромба не возникает.

                        Сейчас придут плюсовики и объяснят тебе, что проблема ромба — это проблема проектирования, а не множественного наследования. Или как-то так.

                        Цитата Qraizer @
                        И тогда возникает другой вопрос: что делать с множественным наследованием? Конечно, ты в курсе о том, как об этом отзываются апологеты языков, где его нет. Мол, оно не нужно, у нас есть агрегация вместо этого.

                        Отсутствие множественного наследования не обосновывается агрегацией «апологетами языков, где его нет». Ты это выдумал.
                        “Object-oriented design is the roman numerals of computing.” — Rob Pike
                        All software sucks
                          Цитата korvin @
                          Запросто. Непонятно, зачем его с наследованием писать.

                          Пример можно? Наследование позволяет не дублировать код, и быстро создавать новые элементы управления на основе существующих.

                          Цитата korvin @
                          А ещё проще глобальную переменную заюзать и дёргать её откуда угодно.

                          Глобальную переменную легко переписать нечаяно в каком то другом месте.
                          Хотя и их используют там, где они оправданы, синглтон никто не отменял :-?

                          Цитата korvin @
                          Так же. Создать объект и посмотреть глазами все методы, которые ты можешь дёргать.

                          Как? Можно примером?
                          Допустим, вот есть у меня класс Checkbox : public Button, у класса checkbox я реализовал функцию отрисовки, все. Теперь у меня есть checkbox, который имеет все те же методы что и кнопка, но выглядит по другому. Как это будет выглядеть с агрегированием? Чтоб у чекбокса были все те же методы?

                          Цитата korvin @
                          Сейчас придут плюсовики и объяснят тебе, что проблема ромба — это проблема проектирования, а не множественного наследования. Или как-то так.

                          Я сам плюсовик, и везде где я видел множественное наследование, оно рано или поздно приводило к ромбовидному, практически неизбежно, особенно, когда система большая.
                          Сообщение отредактировано: Wound -
                            Цитата Wound @
                            Возьми какие нибудь игры, наследованием проще выстраивать иерархии объектов. Ведь проще создать потомка, и вызвать у него нужный метод, чем через объекты вызывать цепочку адского треша.
                            НУ так именно это я и сказал. "Проще" ведь не означает "иначе никак".
                            Цитата Wound @
                            Что до множественного наследования, например в том же C# множественное наследование классов запрещено, для интерфейсов разрешено. И проблема ромба не возникает.
                            Вот поэтому и говорят правильнее: множественное наследование реализаций. Интерфейсы не наследуются, они реализуются, поэтому и ромбов нет.
                            А что касается проблемы ромбов, то я уже многократно говорил, что её не существует. Опять же, никто, отмечая пресловутую "проблему ромба", не может внятно ответить, как ему быть, если разные интерфейсы, подлежащие реализации в неком классе, окажутся конфликтующими друг с другом. Внезапно "проблема ромба" оказывается не ограничивающейся только реализациями. Если же некто расскажет, что мол в интерфейсах она легко решается, то на просьбу показать, как, приводит ровно те же приёмы, что и при наследовании реализаций.

                            Добавлено
                            Цитата korvin @
                            Сейчас придут плюсовики и объяснят тебе, что проблема ромба — это проблема проектирования, а не множественного наследования. Или как-то так.
                            Уже. Только не проблема, а задача.
                            Сообщение отредактировано: Qraizer -
                            Одни с годами умнеют, другие становятся старше.
                              Цитата Qraizer @
                              А что касается проблемы ромбов, то я уже многократно говорил, что её не существует.

                              Почему? Или в смысле? Просто не совсем понял.

                              Цитата Qraizer @
                              Опять же, никто, отмечая пресловутую "проблему ромба", не может внятно ответить, как ему быть, если разные интерфейсы, подлежащие реализации в неком классе, окажутся конфликтующими друг с другом.

                              Не совсем понял. Реализуются оба интерфейса в одном классе. Т.е. ты реализуешь 2 созвучных метода от разных интерфейсов в классе, который их реализует.
                                Цитата korvin @
                                Отсутствие множественного наследования не обосновывается агрегацией «апологетами языков, где его нет». Ты это выдумал.
                                Я бы с удовольствием это выдумал, но увы, приходится цитировать. На самом деле корень ровно в том, что чаще всего такие дискутируемые стороны сами не разбираются в том, о чём спорят. Точнее, не понимают того, что говорят о разных вещах. И те правы, что множественное наследование реализаций суть нормальная вещь, и те, что утверждают, мол, оно нафик не нужно, ибо агрегация. Решение практически любой подобной дискуссии простое, но крайне для них неочевидное: наследование само по себе маловостребованная вещь, и очень часто, гораздо чаще, чем они себе представляют, может быть заменена на агрегацию. А нередко и должна. И это будет более правильным проектным решением. Причём я сейчас за простое наследование.
                                Просто надо осознать, что это разные патерны, служащие разным целям. И друг с другом за области применения не конфликтующие. А все проблемы на стыке их применения возникают от недостаточной грамотности программера, выбирающего то или иное.

                                Добавлено
                                Цитата Wound @
                                Не совсем понял. Реализуются оба интерфейса в одном классе. Т.е. ты реализуешь 2 созвучных метода от разных интерфейсов в классе, который их реализует.
                                Тебе на Плюсах?
                                ExpandedWrap disabled
                                  struct ICoolInterface
                                  {
                                    virtual void madeMeCool() = 0;
                                  };
                                   
                                  struct ICoolerInterface
                                  {
                                    virtual void madeMeCool() = 0;
                                  };
                                   
                                  struct CCoolImpl: ICoolInterface, ICoolerInterface
                                  {
                                    /* и чё тут писать? */
                                  };
                                Одни с годами умнеют, другие становятся старше.
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (8) 1 [2] 3 4 ...  7 8 все


                                Рейтинг@Mail.ru
                                [ Script Execution time: 0,1552 ]   [ 16 queries used ]   [ Generated: 18.11.19, 21:22 GMT ]