Entry tags:
OOП, немного Python и Ruby
Коля Голубев (
nickolaygolubev) и Вова Байда (
vbayba) продолжают потихоньку ковырять Python,
в отличие от меня.
Оказывается,дельфин и не рыба вовсе там метод __init__
- не конструктор, а нечто, что вызывается "после коструирования"
пустого объекта. Разница, как на меня, отсутствует. Тем более что
только __init__ создаёт все поля класса.
Это значит, если вы хотите пронаследоваться от другого класса, нужно вызвать его __init__ из своего. А последнее значит, что конструктор вашего класса может сам выбирать, от какого класса ему наследоваться. Забавно, factory прямо в конструкторе.
Недавно думал, по какой книжке учить студентов ООП. И обнаружил, что не знаю.
Да, "Рефакторинг" содержит много хороших и вдохновляющих идей, но они там размазаны.
Буч слишком толстый, на C++, да его и не рекомендовал
alf_kadett.
Рекомендовал Бадда, видимо, "An Introduction to Object-Oriented Programming".
Программу по ООП отлично составил Богдан Пришедько. Он взял:
Сергей (
salpaev) сказал, что Буч действительно плох.
Рекомендовал:
Сергей же снова вернулся к скриптовым языкам и сказал, что без IDE с code completion и рефакторинга хотя бы на уровне move method порог изучения языка гораздо выше. Он бы выучил Ruby, если бы не приходилось каждый раз лазить в доку, чтобы узнать, какие методы есть в классе Array или HashTable.
И сделал вывод, что нас ждёт нашествие блондинок со знанием C#.
![[livejournal.com profile]](https://www.dreamwidth.org/img/external/lj-userinfo.gif)
![[livejournal.com profile]](https://www.dreamwidth.org/img/external/lj-userinfo.gif)
Оказывается,
Это значит, если вы хотите пронаследоваться от другого класса, нужно вызвать его __init__ из своего. А последнее значит, что конструктор вашего класса может сам выбирать, от какого класса ему наследоваться. Забавно, factory прямо в конструкторе.
Недавно думал, по какой книжке учить студентов ООП. И обнаружил, что не знаю.
Да, "Рефакторинг" содержит много хороших и вдохновляющих идей, но они там размазаны.
Буч слишком толстый, на C++, да его и не рекомендовал
![[livejournal.com profile]](https://www.dreamwidth.org/img/external/lj-userinfo.gif)
Программу по ООП отлично составил Богдан Пришедько. Он взял:
- описание АТД
- естественно, три кита - инкапсуляцию, наследование, полиморфизм... кстати, а кто выделил именно эти три? Я не нашёл;
- coupling and cohencion;
- семь приципов: Open Closed (откуда бишь это?), Liskov substitution, Dependency Inversion, Interface Segregation, Composite Reuse, Least Knowledge
- признаки "вони" кода у Фаулера;
- Рекомендации по АТД и проектироваанию классов у МакКоннелла;
Сергей (
![[livejournal.com profile]](https://www.dreamwidth.org/img/external/lj-userinfo.gif)
Рекомендовал:
- Rebecca Wirfs-Brok: "Designing Object-Oriented Software" - у неё он нашёл объяснения многим своим, как он когда-то считал, неправльным решениям - data object, stateless objects, объекты-методы и т.п. Она же критикует design patterns, например, рассматривает случаи, когда вроде бы под ситуацию неплохо подходит паттерн из GoF, а если подумать - получается совсем другой дизайн. Ну, в последний случай я не очень верю, думаю, если присмотреться, там будет либо не очень паттерновая ситуация, либо новое решение тоже окажется паттерном :)
- Лармана - "Applying UML and design patterns", только не 3е издание, а раньше. В 3м тот приплёл буззворды вроде "agile development", что не пошло книге на пользу;
- DDD - Domain-driven design Эванса, в обязательном порядке;
- Майерс "Effective C++" тоже сильно помог понять ООП, показал много новых приёмов типа двойной диспетчеризации.
Сергей же снова вернулся к скриптовым языкам и сказал, что без IDE с code completion и рефакторинга хотя бы на уровне move method порог изучения языка гораздо выше. Он бы выучил Ruby, если бы не приходилось каждый раз лазить в доку, чтобы узнать, какие методы есть в классе Array или HashTable.
И сделал вывод, что нас ждёт нашествие блондинок со знанием C#.
no subject
Вы пробовали реализовывать Open/Closed на практике? Мне кажется, это будет сплошной Copy/Paste и overengineering.
no subject
Мне кажется, он применим, но довольно редко: когда мы делаем API для специфического случая.
Хотя, он противоречит принципу "заменяйте наследование агрегацией, где можно". Обычно я таки-предпочитаю давать интерфейс (open по определению) как callback клиентскому коду, и агрегировать его в свой полностью closed класс.
Хотя, да, я делал классы, в которых наследники могли и должны были переопределить один или два метода. И да, это иногда приводит к copy-paste - когда в наследнике нужно выполнить только ЧАСТЬ или вариацию на тему функциональности предка. А overengineering-а не замечал, наоборот, чтобы вынести переопределяемый метод в отдельный интерфейс, придётся вводить этот самый интерфейс - новую сущность.
Про "заменяйте наследование агрегацией" в учебном курсе тоже было :)
no subject
З. Ы. >> что нас ждёт нашествие блондинок со знанием C# - бу-го-га, дык... я - первая ласточка ? :-D
no subject
Определённо :-]]]
no subject
no subject
no subject
no subject
no subject
Если в учебном курсе и было "заменяйте наследование агрегацией" то это было заблуждением, которому поддавались первобытные архитекторы и тренеры.
no subject
Наследование B от A можно заменять агрегацией, когда B по коду нужно только использовать функциональность A, но не быть его экземпляром.
no subject
no subject
no subject
no subject
Если правило ремесла работает в 95% случаев, это уже очень хорошее правило (сравни с open-closed). В 5% срабатывает оговорка "...если это не потребует ввести одну-две лишние сущности", ну так одним правилом никакой приём ремесла и не описывается.
no subject
Нет. Именно значения на ссылки. Советовал это делать Страуструп(если мне не изменяет память) мотивируя это тем что при передаче\возвращении по значению объект копируется а это требует дополнительного времени и памяти. А по ссылке передавать типа оптимально. Вот преждевременная оптимизация многих и сгубила.
no subject
no subject
no subject
no subject
no subject
no subject
По поводу конста - когда ты возвращаешь локальный объект по ссылке то там const пофигу.
no subject
Правило на ВСЕ случаи жизни вывести нельзя, даже "переходя дорогу, посмотри налево", не сработает в Англии. Но ты делаешь неправильный вывод - что вообще никакими правилами пользоватья нельзя. В реальной жизни, не в математической абстракции, "правилом" можно называть высказвыание, верное в 80% случаев, ну и исключения из него тоже надо знать.
no subject
no subject
no subject
Идея со ссылками была плохой, но это не значит, что ЛЮБОЕ правило, из которого бывают исключения, приносит больше вреда, чем пользы.
no subject
Кстати ещё из этой оперы правило: "используйте интерфейсы вместо абстрактных классов, где возможно"
no subject
no subject
И в идеале - ссылку на хотя бы одну методику объектно-ориентированного анализа, если ты не веришь перечисленным источникам.
no subject
no subject
Менее фатальные ошибки - вместо наследующих друг-друга интерфейсов будут появлятся агрегирующие друг-друга классы с setter\getter-ами.
> И в идеале - ссылку на хотя бы одну методику объектно-ориентированного анализа, если ты не веришь перечисленным источникам.
Не надо "давить авторитетом". Покажи мне в этих источниках цитату в которой сказано что агрегацию надо использовать вместо наследования везде где только можно?
no subject
А у меня на собеседованиях каждый первый кто знает что такое ссылка возвращает в operator+()-е ссылку на локальный объект.
А те кто собеседование всё-таки проходят в бейс курсе в operator+()-е возвращают ссылку уже не на локальный объект а на объект из статического пула.
И это проблема создана именно образованием.
no subject
no subject
Fowler Analysis patterns
GOF Пример в начале
Дизайн хороших библиотек, например HotDraw
ИМХО человек должен полюбить процесс создания дизайна, после такой зацепки дальше сам разберется.
no subject
http://ru.smalltalk.wikia.com/wiki/ПРИНЦИПЫ_ОО_ДИЗАЙНА
no subject
Плюс я выступаю не столько против правил сколько против того как они преподносятся. Меня неустраивает именно форма "заменяйте X на Y, где можно".
no subject
Ошибаешься. Во-первых, обычно квадрат является фигурой и правило нельзя применить. Во-вторых, я как-то раз заменил наследование агрегацией именно в этом случае, когда форма была всего лишь поведением. Ничего страшного не случилось, наоборот, квадрат стало легче юнит-тестировать отдельно от фигуры.
Менее фатальные ошибки - вместо наследующих друг-друга интерфейсов будут появлятся агрегирующие друг-друга классы с setter\getter-ами.
Обычно у полей для делегирования/полиморфизма вообще нет публичных аксесоров, только инициализация в конструкторе.
Не надо "давить авторитетом". Покажи мне в этих источниках цитату в которой сказано что агрегацию надо использовать вместо наследования везде где только можно?
Ты первый начал. Я изначально ссылался только на своё мнение, а потом на конкретные книги.
Java Design: Objects, UML, and Process. Ссылается на GoF.
Fine-tuning Abstraction @ Java boutique.
Собственно GoF, страница 34:"Как решать задачи проектирования" — "Наследование и композиция": "Это подводит нас ко второму правилу объектно-ориентированного проектирования: предпочитайте композицию наследованию класса. [...] С помощью делегирования композицию можно сделать столь же мощным инструментом повторного использования, сколь и наследование [Lie86, JZ91]."
no subject
Кстати, если ты читаешь правило буквально, то "где можно" не означает "везде".
no subject
Ты немного поторопился с выводами насчёт качества этого правила.
no subject
Мне не нравяться все такие правила, потому что ответ на вопрос "где можно" более приорететный чем ответ на вопрос "что на что можно заменять". Сначала надо объяснять "где можно" а потом уже расказывать что на что в этих случаях можно/целесообразно заменить.
Правило это буквально понимаю не я, а ньюкамеры которые ещё не знают "где можно" и поэтому стараются заменять везде.
no subject
а тем более "С помощью делегирования композицию можно сделать столь же мощным инструментом повторного использования, сколь и наследование"
и
"Заменяйте наследование агрегацией, где можно"
Это абсолютно разные вещи. Против правила в формулировке ГоФ я ничего против не имею.
no subject
1. "Предпочитайте X Yу" подразумевает при прочих равных условиях.
2. "Заменяйте X на Y, где можно" подразумевает что даже если в контексте более уместным будет использование X, и в сторону использования X больше аргументов "за", но есть хоть небольшая возможность или намёк на то что-бы использовать Y - то надо использовать Y.
"Заменяйте X на Y, где можно" более сильное правило чем "Предпочитайте X Yу".
+ Я так понимаю ГоФ сперва как я уже и говорил сначала объяснили контекст "где можно", а уже потом дали правило предпочтения.
no subject
no subject
no subject
Во первых не надо списывать со счетов рефакторинг. Если наследование в коде "не на своём месте" и по логике вместо него должна быть агрегация, то такое наслодавние надо именно заменить агрегацией.
Во вторых смысл остался тот-же самый. Даже если по логике должно быть наследование всё равно надо будет по этому правилу выбирать агрегацию если есть хоть какая-то возможность её использовать.
В итоге "выбирайте" ещё более плохое правило чем "заменяйте"
no subject
Смотри. Обратная сторона медали. В С++ friend-ы совсем негодная технология. В этом случае правило будет звучать так: "Заменяйте friend-ы паттерном visitor везде" (или для мастеров ДАО - "... везде где вам не лень"). В этом случае visitor будет всегда предпочтительнее friend, но опять в правиле нету "..., где можно". Если-бы он там был то новички подумали бы "я не знаю что такое visitor значит в этом конкретном случае на friend его заменить нельзя. Буду использовать friend а если меня наругают, скажу что это именно тот случай когда нужен friend а не visitor". Так собственно говоря было и с макросами.
Посоветуйте сайт с музыкой для начинающего рэппера
(Anonymous) 2008-01-19 04:32 am (UTC)(link)Я - начинающий брейкдансер. Хочу посмотреть новые элементы брейкданса.
Где и как это можно сделать, цена?
no subject