Aleksei (astynax) 
    
    
        
        
        
        Можно просто не наследоваться :) Только копмозить
    
 
    
    Alexander 
    
    
        
        
        
        тогда это уже не классическое ООП
    
 
    
    Alexander 
    
    
        
        
        
        про которое обычно говорят апологеты этого стиля
    
 
    
    Alexander 
    
    
        
        
        
        и прекрасно выражается в не-ООП языках
    
 
    
    Aleksei (astynax) 
    
    
        
        
        
        Только преподы ООП, разве что
    
 
    
    Aleksei (astynax) 
    
    
        
        
        
        Практики знают, что композиция лучше наследования!
    
 
    
    Alexander 
    
    
        
        
        
        я видел интырпрайз явакод
    
 
    
    Aleksei (astynax) 
    
    
        
        
        
        Все книжки про паттерны об этом говорят
    
 
    
    Alexander 
    
    
        
        
        
        при этом 3/4 паттернов полагаются на наследование?
    
 
    
    Aleksei (astynax) 
    
    
        
        
        
        Нет, композиции хватает
    
 
    
    Anton 
    
    
        
        
        
        Ну вот типы-суммы и типы-произведения — очень простые вещи, которые можно комбинировать как угодно. Интерфейсы/трейты тоже — их можно как при статической, так и при динамической диспетчеризации использовать. А наследование включает в себя слишком много всего сразу, поэтому очень легко получить кашу, которую потом сложно зарефакторить
    
 
    
    Anton 
    
    
        
                    
                        
                            
                            Нет, композиции хватает
                        
                    
                
        
        
        Композиции не хватает, когда в базовом типе 20 методов, а в наследнике добавляется один, и приходится все 20 пробрасывать руками
    
 
 
    
    Aleksei (astynax) 
    
    
        
        
        
        Это уже должен решать язык, аннотациями, или ещё чем
    
 
    
    Anton 
    
    
        
        
        
        Ну я считаю, что такое пробрасывание надо делать явной отдельной концепцией в языке
    
 
    
    Anton 
    
    
        
        
        
        В расте не хватает такого
    
 
    
    Anton 
    
    
        
        
        
        Но я глупенький) Может быть есть лучше решения
    
 
    
    Aleksei (astynax) 
    
    
        
        
        
        В питоне есть метапрограмминг, делегацию можно автоматизировать. А встраивать именно в язык не очень хорошо, да
    
 
    
    Aleksei (astynax) 
    
    
        
        
        
        В расте хотят расширяемые рекорды запилить, еяпп. Но когда запилят, не знаю
    
 
    
    Anton 
    
    
 
    
    Aleksei (astynax) 
    
    
        
        
        
        "OOP as a Library", лучше, чем некая всегда чем-то неполоноценная версия ООП, намертво встроенная в синтаксис
    
 
    
    Anton 
    
    
        
        
        
        Ну это не ООП, я именно за то, чтобы делегацию сделать отдельно от остального
    
 
    
    Anton 
    
    
        
        
        
        По сути просто бойлерплейт убрать
    
 
    
    Anton 
    
    
        
        
        
        delegate to base {
           fn1, fn2, fn3
        }
        
        Что-нибудь типа такого
    
 
    
    Aleksei (astynax) 
    
    
        
        
        
        В питоне я могу сделать так:
        class Foo(
                compose(bar=Bar,
                    delegate=['write', 'read', 'size']),
                compose(qux=Qux, delegate=ALL)):
            ...
    
 
    
    Anton 
    
    
        
        
        
        Ага
    
 
    
    Aleksei (astynax) 
    
    
        
        
        
        Тут хотя бы не будет той же проблемы с множественным наследованием, от которого в питоне одна боль
    
 
    
    Aleksei (astynax) 
    
    
        
        
        
        А вообще в питоне или том же Ruby я могу неизвестные методы пробрасывать во все вложенные объекты по порядку, пока кто-то из них не обработает. Так что можно даже особо не делегировать. Правда и интроспекции не будет тогда
    
 
    
    Alexander 
    
    
        
        
        
        тут надо чтобы тот кому делегировали мог вызвать асирактный метод, который будет выполнен тем, кто делегировал
    
 
    
    Alexander 
    
    
        
        
        
        абстрактный
    
 
    
    Aleksei (astynax) 
    
    
        
        
        
        Ну да, получится двойная диспетчеризация
    
 
    
    Alexander 
    
    
        
        
        
        ООП и наследование об этом
    
 
    
    a66ath 
    
    
 
    
    Aleksei (astynax) 
    
    
        
        
        
        При композиции вложенный объект не должен знать ничего об оборачивающем - это утечка абстракции
    
 
    
    Aleksei (astynax) 
    
    
        
        
        
        Разве что передать при вызове колбэк можно, если это соответствуте API вкладываемого объекта
    
 
    
    Anton 
    
    
        
        
        
        Короче очень неортогональная штука это наследование)
    
 
    
    Aleksei (astynax) 
    
    
        
        
        
        Наследование сначала смотрится неплохо, а потом начинается адище
    
 
    
    Aleksei (astynax) 
    
    
        
        
        
        Иерархии сущностей адекватные написать нелегко, часто - невозможно. А ещё чаще - просто не нужно, но "все привыкли уже"
    
 
    
    Зигохистоморфный 
    
    
        
        
        
        Ох и развели вы тут)
    
 
    
    Alexander 
    
    
 
    
    Alexander 
    
    
        
        
        
        и не особо нужная :)
    
 
    
    Alexander 
    
    
        
        
        
        зачастую вложенный объект все же должен знать какой-то интерфейс
    
 
    
    Alexander 
    
    
        
        
        
        ну или по другому выкручиваться, а вот с иерархиями согласен
    
 
    
    Alexander 
    
    
        
        
        
        там наверху пример с Боингом был
    
 
    
    Alexander 
    
    
        
        
        
        я там не как птиц наследовать и что делать с самолётами двойного назначения
    
 
    
    Alexander 
    
    
        
        
        
        меняют ли они класс в военное время
    
 
    
    доня. 
    
    
        
                    
                        
                            
                            ну это уже похоже на классическое наследование
                        
                    
                
        
        
        не
        важно то что такие интерфейсы ничего не знают о том как объект устроен внутри
        то есть они описывают только поведение (и неважно что у каких-то методов оно может быть дефолтным)
    
 
 
    
    доня. 
    
    
        
                    
                        
                            
                            и не особо нужная :)
                        
                    
                
        
        
        да ладно, вот простейший пример
        есть какая-нибудь ORM, надо шоб она могла подключаться к разным БД
        плохой способ: хардкодить подключение к каждому типу БД в одной структуре
        тоже плохой способ: наследоваться от общей структуры и в наследниках перегружать метод подключения к БД
        чёткий способ: выделить подключение к БД в отдельный интерфейс Connection и хранить ссылку на Connection в качестве поля структуры ORM
        таким образом ORM знает только об универсальном интерфейсе предоставляемым структурами, реализующими Connection
        и можно в пользовательском коде реализовать подключение к какой-нибудь БД о которой разработчик ORM не знает
    
 
 
    
    Alexander 
    
    
        
        
        
        какое отношение это имеет к наследованию или композиции?
    
 
    
    доня. 
    
    
        
        
        
        прямое
    
 
    
    доня. 
    
    
        
        
        
        второй способ - наследование, третий - композиция
    
 
    
    доня. 
    
    
        
        
        
        (простите за мой Rust):
        
        type ConnectionResult = ...;
        
        trait Connection {
          fn connect(&mut self) -> ConnectionResult;
        
          // more methods
        }
        
        struct ORM {
          connection: Box<Connection>;
        
          // more fields
        }
    
 
    
    Alexander 
    
    
        
        
        
        в данном случае data Connection = Connection { method1, method2 } хватит
    
 
    
    Alexander 
    
    
        
        
        
        что правда тоже самое, но в профиль
    
 
    
    доня. 
    
    
        
        
        
        нуу или так
        хотя мне-таки больше нравится вариант где Connection - интерфейс/трейт/тайпкласс
    
 
    
    доня. 
    
    
 
    
    Aleksei (astynax) 
    
    
        
        
        
        абстрактный, но реализуемый :)
    
 
    
    Alexander 
    
    
        
        
        
        ну с Haskell можно подобное
    
 
    
    Alexander 
    
    
        
        
        
        data Connection; class HasConnection ; class AsORM a where default .. :: HasConnection a => a -> ...
    
 
    
    доня. 
    
    
        
                    
                        
                            
                            абстрактный, но реализуемый :)
                        
                    
                
        
        
        ну так-то реализовать достаточно просто)
        проблема только в том что одно дело когда популярная либа, другое - когда используешь свой костыль
        костыль не в том плане что плохо реализован, а в том что никто больше этим подходом не пользуется и рандомный человек заглянув в твой код будет учить чуть ли не новый язык, привыкая использовать кастомный механизм делегирования вместо встроенного в питон наследования
    
 
 
    
    Alexander 
    
    
        
        
        
        HasConnection через Generic
    
 
    
    доня. 
    
    
        
        
        
        @qnikst можно ж через экзистенциальную квантификацию, а то с дженериками немного громоздко
    
 
    
    Alexander 
    
    
        
        
        
        не, это совсем разные вещи :)
    
 
    
    доня. 
    
    
        
        
        
        я имел ввиду что-то типа
        
        {-# LANGUAGE ExistentialQuantification #-}
        
        class Connection c where
            connect :: c -> IO ()
        
        data ORM = forall c. Connection c => ORM { connection :: c }
        
        (сигнатура connect не особо осмысленная, но не суть)
    
 
    
    Alexander 
    
    
        
        
        
        здесь тогда класс такой вообще не нужен
    
 
    
    Alexander 
    
    
        
        
        
        взять структуры данных и все
    
 
    
    Alexander 
    
    
        
        
        
        в которой поля это методы
    
 
    
    кана 
    
    
        
        
        
        Я, как новичок, просто использовал бы ReaderT для передачи коннекшона, а код, который работает с базой, требовал бы тот самый тайпкласс для енва в ридере, что позволит один и тот же код запускать с разными коннекшонами (чтобы замокать для тестов, например).
        
        Я пока не писал ни одного продакшенового кода на хаскеле, если что, могу нести хрень
    
 
    
    Alexander 
    
    
        
        
        
        а это уже совсем другое
    
 
    
    доня. 
    
    
        
        
        
        нуу не знаю, мне кажется что вариант с полями-методами какой-то менее структурированный
        может я и не прав конечно
    
 
    
    доня. 
    
    
        
                    
                        
                            
                            Я, как новичок, просто использовал бы ReaderT для передачи коннекшона, а код, который работает с базой, требовал бы тот самый тайпкласс для енва в ридере, что позволит один и тот же код запускать с разными коннекшонами (чтобы замокать для тестов, например).
                    
                    Я пока не писал ни одного продакшенового кода на хаскеле, если что, могу нести хрень
                        
                    
                
        
        
        хм, а это получается можно сказать Reader тут выступает в роли такого функционального IoC-контейнера?
    
 
 
    
    кана 
    
    
        
        
        
        Ну как я понимаю ридер, он для этого и нужен, чтобы упростить передачу одной и той же зависимости куче кода без кучи лишних аргументов
    
 
    
    Зигохистоморфный 
    
    
 
    
    Зигохистоморфный 
    
    
        
        
        
        https://twitter.com/mokevnin/status/903909806901166080
    
 
    
    Зигохистоморфный 
    
    
        
        
        
        https://gist.github.com/mbbx6spp/899e7813ada901c9ffea4ac157bc361a
    
 
    
    Евгений 
    
    
 
    
    Зигохистоморфный 
    
    
        
        
        
        думаю без ооп классов
    
 
    
    Aragaer 
    
    
        
        
        
        я нормально программирую без классов
    
 
    
    Зигохистоморфный 
    
    
        
        
        
        есть)