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

    Ну на плюсах как раз таки есть множественное наследование. В C# напишем:
    ExpandedWrap disabled
      using System;
       
      interface Device1
      {
          void start();
      }
       
      interface Device2
      {
          void start();
      }
       
      public class ConcreteDevice : Device1, Device2
      {
          void Device1.start()
          {
              Console.WriteLine("Device1 implementation");
          }
          
          void Device2.start()
          {
              Console.WriteLine("Device2 implementation");
          }
       
      }
       
      public class Test
      {
          public static void Main()
          {
              Device1 d1 = new ConcreteDevice();
              Device2 d2 = new ConcreteDevice();
              
              d1.start();
              d2.start();
          }
      }

    https://ideone.com/hfL7rP
      Цитата Qraizer @
      наследование само по себе маловостребованная вещь, и очень часто, гораздо чаще, чем они себе представляют, может быть заменена на агрегацию. А нередко и должна. И это будет более правильным проектным решением. Причём я сейчас за простое наследование.
      :yes: :yes: :yes:
      Причем, по моим наблюдениям, от ООП/Ынтырпрайза головного мозга чаще всего страдают наслаждаются джависты и шарписты. Вот обязательно им все нужно запихнуть в иерархию классов.

      Добавлено
      Цитата Wound @
      Я сам плюсовик, и везде где я видел множественное наследование, оно рано или поздно приводило к ромбовидному, практически неизбежно, особенно, когда система большая.
      Вот жеж везло тебе. Я никогда не видел проблемы ромба, окромя как на бумаге.
      Сообщение отредактировано: applegame -
        Цитата applegame @
        Вот жеж везло тебе. Я никогда не видел проблемы ромба, окромя как на бумаге.

        Нигде не встречал конструкций вида:
        ExpandedWrap disabled
          class SomeClass : virtual public SomeBase

        ??
        Ну так может тебе не доводилось видеть/юзать множественное наследование, окромя как на бумаге, вот и не видел? :-? А я насмотрелся уж на это...
          Цитата Wound @
          Ну так может тебе не доводилось видеть/юзать множественное наследование, окромя как на бумаге, вот и не видел?
          Ну в общем-то почти так и есть. Множественное наследование, кроме как наследование интерфейсов, практически не встречалось, ибо как-то нужды в таких извратах не возникало. Даже простое наследование бывало достаточно редко. Я-то гуи не проектирую, больше серверной хренью занимаюсь.
          Сообщение отредактировано: applegame -
            Цитата applegame @
            Причем, по моим наблюдениям, от ООП/Ынтырпрайза головного мозга чаще всего страдают наслаждаются джависты и шарписты. Вот обязательно им все нужно запихнуть в иерархию классов.

            Возьми практически любой проект на том же С++, где есть классы, почти везде есть наследование. Так что тут не одни джависты/шарписты этим страдают.
            Ну и как там в Java хз, шарписты наследуются от интерфейсов в большинстве случаев, а наследование от интерфейсов не приносит тех проблем, о которых тут пытаются рассказать. Тут на сколько я понимаю - про проблемы наследования классов вещают.
            И я как то слабо представляю как можно, без дублирования кода, эффективно использовать агрегирование. Это же придется дублировать все методы из агрегата, в том классе в котором ты его юзаешь. А если у тебя несколько таких агрегатов, то класс превратиться в длинную портянку кода? :-? Или как?
              Цитата Wound @
              Возьми практически любой проект на том же С++, где есть классы, почти везде есть наследование. Так что тут не одни джависты/шарписты этим страдают.
              Я не говорил, что одни джависты/шарписты этим страдают. И я не про наследование вообще, а про неудержимое желание запихать в иерархию все подряд.
              Сообщение отредактировано: applegame -
                Цитата applegame @
                И я не про наследование вообще, а про неудержимое желание запихать в иерархию все подряд.

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

                Добавлено
                Ну и многие технологии/фреймворки завязаны на наследовании, с ними проще работать через наследование.
                  Цитата Wound @
                  Ну не знаю. Мне кажется, что это связано как раз с тем, что если использовать агрегацию, то придется писать просто кучу дублирующихся методов. Просто я пока не понимаю, как это сделать по другому. А это значит классы будут намного сложнее, чем если использовать наследование.
                  Зависит от языка. Например D способен генерить эти методы автоматически на стадии компиляции.
                  Сообщение отредактировано: applegame -
                    Цитата Wound @
                    И я как то слабо представляю как можно, без дублирования кода, эффективно использовать агрегирование. Это же придется дублировать все методы из агрегата, в том классе в котором ты его юзаешь.

                    или просто сделать проперти, которая возвращает интерфейс агрегата.

                    Добавлено
                    Цитата applegame @
                    Зависит от языка. Например D способен генерить эти методы автоматически на стадии компиляции.

                    хммм... заходим на hh.ru и вбиваем "разработчик D"

                    Результат:
                    Цитата
                    Запрос исправлен, по запросу "разработчик D" ничего не найдено


                    Ну нахрен этот D :D
                      Цитата Fester @
                      или просто сделать проперти, которая возвращает интерфейс агрегата.

                      Не, это не просто, это как раз будет костылем и не очень удобным. Т.к. в итоге ты просто запутаешься где и какие методы живут.
                      Сообщение отредактировано: Wound -
                        С чего бы это?

                        ExpandedWrap disabled
                          interface ICar
                          {
                             string Vendor {get;}
                             string Model {get;}
                             IEngine Engine { get; }
                             ...
                          }
                           
                          interface IEngine
                          {
                             string Vendor { get; }
                             int Volume { get; }
                             ...
                          }
                           
                          class MBS500 : ICar
                          {
                             public string Vendor { get {return "Daimler"; } }
                             public string Model { get { return "Mercedes-Benz S500"; } }
                             public IEngine Engine {get; private set; }
                           
                             public MBS500 (IEngine engine)
                             {
                               Engine = engine;
                             }
                          }
                          Цитата Fester @
                          С чего бы это?

                          Ты правда веришь, что ответ на этот вопрос получишь? :D
                            Ну а вдруг? :)
                              Цитата Fester @
                              С чего бы это?

                              1) Интересно, каким боком тут наследование можно засунуть?
                              2) В любом хеловорде всегда все очевидно.

                              По твоему этот пример можно переписать как:
                              ExpandedWrap disabled
                                class MBS500 : Engine
                                {
                                 string Vendor { get; }
                                   int Volume { get; }
                                }

                              ????

                              На машинах наверное сложно будет объяснить, но можно попробовать.
                              Представь что нужно сделать еще одну машину, ровно такую же, как и MBS500, на ее же базе, но называться она будет MBS501, в ней будет все, тоже самое что и в твоей MBS500, но добавляется несколько деталей, которых нет у MBS500, например там люк, кондиционер, пятая или шестая дверь, пулемет там и т.д. Как при такой схеме классов ты это выразишь?
                              Пример не очень удачный, но после твоего ответа, можно придумать удачный пример. Я просто хочу посмотреть, что ты сделаешь в своем примере.

                              Цитата OpenGL @
                              Ты правда веришь, что ответ на этот вопрос получишь?

                              Странный ты. А где я чего не ответил? Или ты просто как обычно решил трольнуть? Обычно это ты с темы съезжаешь.

                              Добавлено
                              Ладно, пока ты думаешь как бы там агрегирование замутить или наследование всунуть, можно привести более удачный пример. Я не знаю работал ты или нет с MFC, но можно взять его за основу и рассмотреть такой пример: https://docs.microsoft.com/en-us/cpp/mfc/re...ss?view=vs-2019
                              Вот есть у тебя вот такое наследование:
                              Цитата

                              Inheritance Hierarchy
                              CObject

                              CCmdTarget

                              CWnd

                              CListBox

                              CCheckListBox

                              Можно сюда добавить еще что то типа:
                              CCheckListBoxWithTreeState(список чекбоксов с тремя состояниями), который наследуется от CCheckListBox

                              Попробуй вот в этой иерархии избавиться от наследования и выразить все через агрегирование. Я надеюсь после этого тебе чуточку понятнее станет, что я имел ввиду. Плюс не забывай, что это один из контролов, есть же еще кнопки, фреймы, списки, переключатели и т.д. И их тоже необходимо выразить через агрегирование. Представил? Теперь представь у тебя все это лежит на форме, у каждого класса хренова туча своих внутренних контролов, а методов нет. Все методы будь добр получай через проперти. Это еще к тому, что сами проперти могут пересекаться. Например там GetWindow, GetParentWindow и подобное. ты действительно думаешь, что будет удобнее отдавать наружу только сами классы, а их методы не дублировать?
                              Ну вот есть у тебя CCheckListBoxWithTreeState, в котором отдельно есть CListBox, отдельно checkbox, отдельно еще там что то. А тебе нужно обработать клик на этом контроле. Какой обработчик из какого проперти надо вызвать? Из CWnd, который спрятан в ListBox, который спрятан в CChecklistBox, который спрятан в CCheckListBoxWithTreeState? CListBox? CCheckListBox? А может быть в каком то другом?

                              Добавлено
                              Я вот как то писал класс CCheckListBoxWithTreeState, давно это было, лет 9 назад. Сперва меня посетила мысль, взять написать отдельно чекбокс с тремя состояниями, который наследуется от обычного чекбокса, потом взять ListBox, ну и скрестить это через агрегирование(композицию в моем случае), т.е. получался класс который имеет чекбокс и listbox. Вполне логично, отказ от наследования в пользу агрегирования. Но как то не очень это получилось на практике. Потому что у чекбокса свои события, у листбокса свои, и они начинают конфликтовать друг с другом. Возможно я еще не опытный был, не знал как подружить, но как то не очень получилось у меня в общем. В итоге проще и быстрее и без лишнего гемороя было взять за основу CCheckListBox, отнаследоваться от него, переопределить у него DrawItem, и руками нарисовать там чекбокс, с третьим состоянием, добавить ему обработчики события. И все заработало и наступил мир во всем мире.

                              Добавлено
                              Странно что ты Fester читал, читал и даже примера не написал. А я уверен что ты бы написал в рабочем проекте вот такую иерархию:
                              ExpandedWrap disabled
                                interface ICar
                                {
                                   string Vendor {get;}
                                   string Model {get;}
                                   IEngine Engine { get; }
                                   ...
                                }
                                 
                                interface IEngine
                                {
                                   string Vendor { get; }
                                   int Volume { get; }
                                   ...
                                }
                                 
                                class MBS500 : ICar
                                {
                                   public string Vendor { get {return "Daimler"; } }
                                   public string Model { get { return "Mercedes-Benz S500"; } }
                                   public IEngine Engine {get; private set; }
                                 
                                   public MBS500 (IEngine engine)
                                   {
                                     Engine = engine;
                                   }
                                }
                                 
                                public class MBS501 : MBS500
                                {
                                   public string Model { get { return "Mercedes-Benz S501"; } }
                                 
                                   public MBS501 (IEngine engine)
                                   {
                                     Engine = engine;
                                   }
                                 
                                   /*тут дополнительные примочки какие то*/
                                }

                              Да и тут бы ты ее написал скорее всего - потому что это логично. А речь идет о том, что так делать нельзя, потому что это приводит к ошибкам.
                              Сообщение отредактировано: Wound -
                                Цитата Wound @
                                А где я чего не ответил?

                                Каюсь, в данном конкретном случае ты вполне нормально на вопрос ответил :yes-sad:
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (8) 1 2 [3] 4 5 ...  7 8 все


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0483 ]   [ 18 queries used ]   [ Generated: 24.04.24, 16:48 GMT ]