Re[5]: Почему объектно-ориентированное программирование пров
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 20.02.11 19:47
Оценка:
Здравствуйте, vdimas, Вы писали:

У тебя исходный тезис — что рефакторинг это зло — неверен.
... << RSDN@Home 1.2.0 alpha 5 rev. 1495 on Windows 7 6.1.7600.0>>
AVK Blog
Re[7]: Почему объектно-ориентированное программирование пров
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 20.02.11 19:47
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Не обращал тут внимание на мнения коллег, что иерархии/системы ООП относительно неплохо работают на небольших и средних задачах (уточнять размеры сейчас не будем)?


Это кто такое говорил? Я другое обычно вижу, говорят — что ООП работает хорошо на средних и больших задачах, а вот на маленьких как раз ФП его заруливает многократно.

V>Я, размеется, не призываю всех тут же удариться в глубокий анализ и прочее. Тем более, что на некоторых языках/средах/IDE пошаговый рефакторинг может оказаться более дешевым решением, чем углубленный предварительный анализ.


Рефакторинг и анализ не противоречат друг другу, непонятно с чего ты их противопоставляешь.

V>Может так оказаться, что это была последняя добавленная функциональность в класс, и нафига тогда делать работу, которую никто не оценит?


Стремный очень подход, как на мой вкус.
... << RSDN@Home 1.2.0 alpha 5 rev. 1495 on Windows 7 6.1.7600.0>>
AVK Blog
Re[12]: Почему объектно-ориентированное программирование про
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 20.02.11 22:01
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Здравствуйте, gandjustas, Вы писали:



V>>>>>Пример программы — не модели.

G>>>>Я уже приводил, читай тему.
V>>>Сорри, не могу себе такое позволить, если не трудно кинь ссылку.
G>>Лень искать. Тебе надо — ты ищи.
V>Так и запишем. Примера программы, не являющейся моделью, нет.

Не сливай так откровенно. Ты задавал вопрос, ты не захотел искать хотя я ответ давал.

G>>Гугл вообще не дает точного совпадения по фразе "полностью абстрактный интерфейс".

V>Попробуй по фразе "абстрактный интерфейс", или "интерфейс класса". Прояви воображение, поищи не только на русском.
Ну хватит уже выкручиваться. Нету определения абстрактного интерфейса.

V>Смотри, что пишут даже по языку Java, где это ключевое слово, если не ошибаюсь, было встречено во второй раз, после IDL:

V>

V>An interface in the Java programming language is an abstract type that is used to specify an interface (in the generic sense of the term) that classes must implement. Interfaces are declared using the interface keyword, and may only contain method signatures and constant declarations (variable declarations which are declared to be both static and final). An interface may never contain method definitions.


V>Обрати внимание на выделенное. Ну и на этой же странице есть ссылка на определение понятия interface в IT.

И че? Ты выделил несколько слов, которые на русский переводятся "в общем смысле этого слова". Где тут про абстрактный интерфейс?


G>>Приведи в порядок терминологию, потом продолжим разговор.


V>Ты уже 10-й пост демонстрируешь, что путаешь понятие "интерфейс" с особым типом и ключевым словом конкретного языка. Воистину, вот и выросло next generation. ИМХО, остальное обсуждать бессмысленно, пока не сдвинемся с этой мертвой точки.

Так я и говорю, ты приведи в порядок терминологию, чтобы я или кто-то другой не путал твои понятия интерфейсов.

V>>>Там нет больших иерархий, наверно.

G>>То есть то что ты писал практикой не подтверждается.

V>Я писал для случая больших иерархий. Т.е. пример с небольшими иерархиями ничего не подтверждает, а всего-лишь неподходит.

Так приведи пример, который подтверждает твои слова.

V>Ну и, они таки есть, эти большие иерархии, в прикладных либах дотнета, хоть и используется больше техника абстрактных классов, чем интерфейсов.

Но мы говорили про интерфейсы.

V>Коментарии по этому поводу уже давал в этой же ветке, ты невнимателен.

Ты пытался увести тему разговора. Что бы ты не забыл напомню твое утверждение: что имеют смысл большие иерархии интерфейсов.
Это утверждение с практикой расходится, никто не создает такие иерархии, они никому не нужны.

V>Так же предлагал сравнить с библиотеками GUI от Java, например AWT.

Мимо кассы, в GUI фреймворках иерархии создают большой процент повторного использования кода. Но чем более глубокая иерархия, тем больше с ней возникает проблем (сколько человек могут навскидку сказать от какого класса надо наследоваться в WPF для создания своего контрола?)

V>Очень показательно применение интерфейсов в больших иерархиях. Поверь, тут есть куда двигаться дальше, а не топтаться с этим вопросом на месте. Был бы интерес. Пока ты хотя бы краем глаза не посмотришь, обсуждать практически нечего.

Я все видел много раз. А ты мог бы привести пример "показательного использования", а не писать пустые слова.
Re[28]: Почему объектно-ориентированное программирование про
От: artelk  
Дата: 20.02.11 22:09
Оценка: :)
Здравствуйте, vdimas, Вы писали:

V>>>Нет, я обращал внимание на то, что нарушение LSP происходит не в месте проектирования иерархии, а в месте ее использования. Т.е. рассматривать каждую иерархию в отдельности при использовании ее через корень иерархии надо как гомоморфную.

Ну да, если метод принимает параметр по ссылке на корень, то он должен обращатся только к тем методам, которые объявлены в этом классе корня. И нефиг даункастить и дергать методы наследников. Если нужны метода наследника, то сигнатура метода должна быть изменена — чтобы метод принимал по ссылке наследника, а не базу.
V>>>Явная гомоморфность иерархии — это просто способ заранее дать себе линейкой по рукам, дабы неповадно.
Ага, и вместо того, чтобы не даункастить, мы делаем специальные приседания, чтобы даункаст был бессмысленен.
— Так неприятно получать по рукам линейкой!
— Согласен... А давайте руки себе отрубим — так у нас будет гарантия, что линейкой мы по ним никогда не получим!
— Гениально!
Руки, в данном случае — это новые методы в наследниках.

A>>Нифига не понятно.

V>Тем не менее, в этом вся соль. Добавил выделенное курсивом, вдруг поможет.
И тут меня осенило!

Дано: Базовый класс B и его наследник D, функции f1..fN, принимающие параметр по ссылке на B и внутри даункастящие его и дергающие методы D.
Добавляется новый наследник B — класс D2.
Требуется: Обеспечить LSP для класса D2.
Как обеспечить: Вроде бы никак, поскольку при любом раскладе функции f1..fN сломаются, если им передать объект типа D2.
Так что же, LSP нарушен уже в этих f1..fN? Нет, не так — просто здесь обман; функции f1..fN, на самом деле, принимают параметрами объекты типа D, а не B. Просто компайл-тайм проверки этого были зачем-то исскуственно придушены и перенесены в рантайм, а их сигнатуры вводят в заблуждение. И это нарушение типобезопасности, а не LSP — совсем другая тема.
Re[7]: Почему объектно-ориентированное программирование пров
От: samius Япония http://sams-tricks.blogspot.com
Дата: 21.02.11 06:13
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Здравствуйте, samius, Вы писали:


S>>Получается что ООП — это сверху вниз, а ФП — снизу вверх?

S>>ИМХО, ООП не мешает продумывать тщательно как "протаскиваются" данные. Или можно сказать что мешает не ООП, а проектирование сверху в какой-то мере, или даже не проектирование а реализация сверху. Именно она обеспечивает нас неизбежным рефакторингом.

V>Не так. Оба подхода применимы для разработки снизу и сверху. Акцент не на "снизу vs сверху", а на "данные vs акторы".

согласен. Про сверху и снизу — мне показалось что речь об этом.
V>Что происходит при отталкивании от данных? Очень простая, но важная вещь: мы выполняем гораздо больший анализ происходящего ДО созревания цельной картинки, то бишь дизайна, в голове. Мы банально начинаем обладать большей информацией. В советской школе программирования учили разрабатывать сначала данные и алгоритмы их обработки. А выделение в модули — это уже результат анализа получаемого решения, фактически выходит автоматически из анализа кол-ва связей по передаче данных, и деления программы по принципу наибольшей связанности внутри модуля и наименьшей — м/у модулями (древнейший принцип, идет еще из электроники/автоматики).
ООП тоже пытается управлять связностью, но действительно, видимо посылки отличаются. В ООП сначала свыше приходят квадратики, а потом предпринимаются усилия по контролю связей между ними. Во всяком случае у меня так бывает.

V>Разве можно это разделение выполнить, не обладая достаточно подробным списком этих самых связей, то бишь не обладая достаточно полным списком используемых алгоритмов и структурами оперируемых данных? В общем, разработка сверху в ООП в клиническом своем варианте, за который его критикуют — это предварительное разделение на "модули" то бишь относительно независимые единицы — объекты, без обладания достаточной информацией о подробностях реализации. Ну и потом, по мере реализации, эти подробности всплывают, уточняется наше собственное видение решения, и мы наше первоначальное решение вынуждены модифицировать.

У меня возникает обратный вопрос. Разве нельзя оставаясь в рамках ООП выполнить это разделение обладая достаточно подробным списком связей? ООП по Кею — это "все есть объект", а не руководство по декомпозиции на модули.

V>В общем, проблема не в ООП, а в заблуждении относительно того, что предварительная стадия анализа может быть минимальной для большой задачи. Не обращал тут внимание на мнения коллег, что иерархии/системы ООП относительно неплохо работают на небольших и средних задачах (уточнять размеры сейчас не будем)? ИМХО, это от того, что вероятность допустить ошибку при "беглом" анализе на небольших системах меньше.

Да, обращал. Но собственного опыта в ФП нет, кроме как на микрозадачах. Про то как оно будет на небольших и средних — могу только догадываться и экстраполировать опыт с микрозадач.

V>Я, размеется, не призываю всех тут же удариться в глубокий анализ и прочее. Тем более, что на некоторых языках/средах/IDE пошаговый рефакторинг может оказаться более дешевым решением, чем углубленный предварительный анализ. Опять же, пошаговость разработки позволяет получать успешные результаты на каждом шаге, что тоже есть гут, бо позволяет уточнять функциональные требования через обратную связь с заказчиком. Но описанные наблюдения "удачных кейзов" стоит держать в голове, и пытаться формировать в ООП заведомо относительно небольшие "экосистемы" типов, дабы переделки внутри этой экосистемы как можно меньше задевали окружающее. Мое замечание относительно ФП в предыдущем посте лишь показывало, что такая независимость при проектировании от данных получается автоматически, т.е. каждая такая экосистема сама формируется вокруг конкретной структуры данных и алгоритмов по трансформации/обработки этих данных.

Встречный вопрос. глубокий предварительный анализ потоков данных не препятствует итеративной разработке с уточнением требований?

S>>Да, т.е. двумя словами — рефакторинг в ООП может быть сведен к минимуму при некоторых правильных привычках. И обилие рефакторинга в ООП не может быть предъявлено как причина его провала в качестве серебрянной пули. Это я и имел ввиду изначально.


V>Например, основные требования — знать что есть ООП (если набирают програмистов на ООП-языки), знать основные паттерны ООП и библиотеки целевого языка. И еще этот, как его... XML. Это что, требования к профессионалу-программисту?

Да, эта проблема в ООП практике существует. С одной стороны, если взять джуниора, скормить ему ООП, паттерны — это безусловно расширит арсенал среднего джуниора. С другой стороны — такой джуниор во всем начинает видеть иерархии и паттерны, часто не замечая простые решения. Тут все зависит от того, на какую почву лег ООП и паттерны. Лишним оно не будет, так что требовать понимание ООП у профессионала можно. Так это еще и удобно — погонять по 3м китам и перечню ГОФ.
Потому встречный вопрос — что требовать и спрашивать (что бы потенциальный профессионал не ушел к конкуренту)?

S>>Меняется видение — нужно менять класс, а не пихать в него пока он не лопнет. Менять проще пока класс и его ответственность обозримы.


V>Это ты подтверждаешь верность исходного постулата. Конечно, классы меняют, модернизируют. Но не заранее, а когда налицо симптомы такой надобности. Не факт, что перед каждым добавлением новой функциональности стоит заранее всё рефакторить. Может так оказаться, что это была последняя добавленная функциональность в класс, и нафига тогда делать работу, которую никто не оценит? В том смысле, что результаты декомпозии не будут востребованы т.е. не будет последующего добавления функциональности в этот участок кода.


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

S>>Правильное слово какое. По поводу размеров грануляции соображения следующие: крупная грануляция тяготеет к рефакторингу, а мелкая — к усложнению композиции на верхнем уровне. И это вне парадигм. Решение может быть в ведении дополнительных уровней/этажей абстракции.


V>Они и так сами получаются. Деление на слои процесс как бы автоматический, управляется сложностью единичного элемента, которую может обозреть человек. Какое там правило для ф-ий и методов — не больше 1-2 экранов кода? Примерно так.

Автоматический для тех кто уделяет этому достаточно внимания

S>>Просто эти 4 буквы отпугивают любителей разоблачать, понижают температуру дебатов и дают понять что я не настроен воинственно. В общем, на всякий случай


V>Почему нет, кстати? Если воинственность будет означать большее желание что-то доказать и в итоге означает большую аргументированность и полезность информации — это даже кул. Спор с интересным собеседником во-первых, раскручивает его на дележ информации, которую он бы в ответ на простой вопрос давать бы не стал (хотя бы из-за лени или снобизма).

Часто воинственный спор с интересным собеседником заканчивается вместе с желанием начинать его в другой раз.
V>Ну и построение собственных аргументов всегда способсвует наведению порядка в собственной же голове, что тоже всегда гут.
Этим можно заниматься и без состояния войны
Re[6]: Почему объектно-ориентированное программирование пров
От: vdimas Россия  
Дата: 21.02.11 06:28
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>У тебя исходный тезис — что рефакторинг это зло — неверен.


Зло здесь проявляется лишь в обязательности рефакторинга в ООП по мере роста сложности программы. Это банально мешает при совместной разработке. Остальных причин рефакторинга мы вроде не касались, бо они не исключительны для ООП.
Re[8]: Почему объектно-ориентированное программирование пров
От: vdimas Россия  
Дата: 21.02.11 07:44
Оценка:
Здравствуйте, AndrewVK, Вы писали:


V>>Не обращал тут внимание на мнения коллег, что иерархии/системы ООП относительно неплохо работают на небольших и средних задачах (уточнять размеры сейчас не будем)?


AVK>Это кто такое говорил? Я другое обычно вижу, говорят — что ООП работает хорошо на средних и больших задачах, а вот на маленьких как раз ФП его заруливает многократно.


Наверно уточнять размеры таки будем, если выйдем на следующую итерацию. Что касается больших проектов, ИМХО, пока спасает только компонентное программирование. И твое высказываемое наблюдение, что в больших иерархиях удобнее реализовывать интерфейсы, а не наследовать реализации, тому пример. Это же КОП чистой воды. Хотя сей способ на иерархиях среднего размера, скажем прямо, себя не окупает — не тот уровень распараллеливания работы по людям и по собственным мозгам.

AVK>Рефакторинг и анализ не противоречат друг другу, непонятно с чего ты их противопоставляешь.


Второй раз похожее замечание... Наверно от того, что весь рефакторинг был свален в одну кучу. В общем, речь шла не только о рефакторинге, но и об откровенных переделках. Хотя сие на жаргоне мы тоже называли рефакторингом, согласно термина это и не так, разумеется, так что поправка принимается.

Теперь по теме. ИМХО, рефакторинг/переделки, вызванные пересмотром состава и ролей объектов, связан(ы) обратно с уровнем проведенного анализа. Прочие процедуры рефакторинга, которые есть "прихорашивания" и не меняют семантику отдельных объектов, по мне не достойны рассмотрения, т.к. ни на что не влияют. Но первый случай может быть очень болезненным, т.к. может требовать заметной трудоемкости по обеспечению безопасности операций над обновленным множеством инкапсулированных состояний. А в случае конкретного рассмотренного кейза (вынужденного рефакторинга/переделки всвязи с "утяжелением" объектов), это практически всегда требует дополнительной борьбы с ухудшающейся инкапсуляцией. И не факт, что сия борьба оправдана, а не ведется на автомате, по аналогии с другими объектами программы... вот если бы заранее, еще на уровне дизайна, допустить, что можно рассматривать как данные, а что нельзя....

В общем, анализ — это сбор информации о предстоящем проекте, её упорядочивание, и попытка рассмотреть как можно больше сценариев заранее, с целью минимизации "ломающих" изменений в будущем. Собсно эти "изменения" я анализу и противопоставляю.


V>>Может так оказаться, что это была последняя добавленная функциональность в класс, и нафига тогда делать работу, которую никто не оценит?


AVK>Стремный очень подход, как на мой вкус.


Практичный, ничто не мешает в комментах пометить тип как претендент на рефакторинг при повторении симптомов. Мы же не на выставку код готовим, описанное может являться временным решением, и некая необходимая переделка может быть произведена совсем в другом месте, а упомянутый класс будет освобожден от этой временной "кривой" функциональности. В совместной работе стадии рефакторинга/переделок должны быть отделены от стадий разработки, но иногда возникают "блокеры" по функциональности, когда что-то необходимо добавить срочно, дабы не держать коллег. Так что список таких "кандидатов на рассмотрение" может копиться себе в течении дня или нескольких, но реальная трудоемкость по переделке затем может быть потрачена согласно степени устаканивания решения. Желательно не раньше... особенно если используются языки, где не существуют автоматические ср-ва рефакторинга, сравнимого с IDEA/Resharper. В общем, сия тонкость тоже влияет на приоритеты и принимаемые решения.

==================
Ты не самый интересный момент комментируешь. Суть этих постов была в замеченном факте, что давая больше доступа к обрабатываемым данным во внутреннем АПИ, надобность структурного рефакторинга, того самого, когда заметно меняется состав объектов и еще более заметно их роли, почти всегда выходит ниже.
Re[9]: Почему объектно-ориентированное программирование пров
От: FR  
Дата: 21.02.11 08:45
Оценка: +1
Здравствуйте, vdimas, Вы писали:

V>==================

V>Ты не самый интересный момент комментируешь. Суть этих постов была в замеченном факте, что давая больше доступа к обрабатываемым данным во внутреннем АПИ, надобность структурного рефакторинга, того самого, когда заметно меняется состав объектов и еще более заметно их роли, почти всегда выходит ниже.

Кстати функциональщина как раз поощряет (АТД и ПМ) такой больший доступ.
Re[8]: Почему объектно-ориентированное программирование пров
От: vdimas Россия  
Дата: 21.02.11 08:54
Оценка:
Здравствуйте, samius, Вы писали:


S>ООП тоже пытается управлять связностью, но действительно, видимо посылки отличаются. В ООП сначала свыше приходят квадратики, а потом предпринимаются усилия по контролю связей между ними. Во всяком случае у меня так бывает.


У всех так. Я же говорю — сначала разбили программу на квадратики, а потом к концу разработки смотрим, сколько у них там связей вышло. Вроде и удобно, но и телега впереди лошади вышла.


S>У меня возникает обратный вопрос. Разве нельзя оставаясь в рамках ООП выполнить это разделение обладая достаточно подробным списком связей? ООП по Кею — это "все есть объект", а не руководство по декомпозиции на модули.


А это вообще больное место. Не существует формальных способов ООП-дизайна. Во всех примерах ООП-анализа в литературе столько творчества, что единственный полезный совет тут — это потщательнее грызть карандаш.

На самом деле, достаточно помнить, что ООП-не серебрянная пуля, т.е. сам по себе не самодостаточный инструмент. Поэтому стоит использовать (хотя бы очень поверхностно) наработки современных процессов по организации разработки ПО. Тем более, что те индифферентны к выбранной технологии. Я вот всем 19-е и 34-е госты рекомендую. Хотя бы раз в жизни прочесть их стоит (с конспектированием интересного). Ну или RUP, который близок по духу.

Вот, пробеги глазами:
http://www.rugost.com/index.php?option=com_content&amp;task=view&amp;id=95&amp;Itemid=53
http://www.rugost.com/files/15271-02.pdf
http://www.rugost.com/index.php?option=com_content&amp;task=view&amp;id=79&amp;Itemid=52
http://www.rugost.com/index.php?option=com_content&amp;task=view&amp;id=96&amp;Itemid=53
http://www.rugost.com/index.php?option=com_content&amp;task=view&amp;id=97&amp;Itemid=53
http://www.rugost.com/files/10746-3-2001.pdf
http://www.rugost.com/files/15910-2002.pdf
http://www.rugost.com/index.php?option=com_content&amp;task=view&amp;id=108&amp;Itemid=62
http://www.rugost.com/index.php?option=com_content&amp;task=view&amp;id=106&amp;Itemid=62
http://www.rugost.com/index.php?option=com_content&amp;task=view&amp;id=77&amp;Itemid=52

Понятное дело, что ГОСТы помимо процесса зачастую навязывают вид и состав документации, что в условиях отсутствия автоматизированный ср-в для этого не кажется полезным/обязательным в реальной разработке. Поэтому стоит использовать лишь наработки по организации процессов и составу работ. Это помогает планировать, расставлять приоритеты и поменьше грызть карандаш.


V>>В общем, проблема не в ООП, а в заблуждении относительно того, что предварительная стадия анализа может быть минимальной для большой задачи. Не обращал тут внимание на мнения коллег, что иерархии/системы ООП относительно неплохо работают на небольших и средних задачах (уточнять размеры сейчас не будем)? ИМХО, это от того, что вероятность допустить ошибку при "беглом" анализе на небольших системах меньше.

S>Да, обращал. Но собственного опыта в ФП нет, кроме как на микрозадачах. Про то как оно будет на небольших и средних — могу только догадываться и экстраполировать опыт с микрозадач.

А не обязательно чистое ФП, со всеми модными фокусами. ФП сидит на функциональной декомпозиции, а это практически первое, чему учатся при обучении программированию. Ну и если есть опыт по созданию/использованию делегатов в том же C#, то еще одним "китом" ФП ты уже владеешь. Прочие ленивости и замыкания — это лишь доп. выразительные ср-ва инструмента, т.е. те, которые не критичны, т.к. в случае надобности реализуются "в лоб". Хотя со вторым упомянутым в шарпе тоже порядок. Ну и плюс, ФП в "чистом" виде не совсем удобно (лично мне, например). Какая-никакая группировка функциональности в объекты помогает в восприятии происходящего в собственной программе, сие факт. Поэтому речь была не о переходе на чистое ФП, а о заимствовании полезных подсмотренных практик, кои не только в иммутабельности заключаются, но во взгляде на шаги решения задачи как на стадии трансформации данных. Отсекая заранее спекуляции — разумеется и это не для всех задач удобный поинт. Речь о том, чтобы расширить взгляд на задачу, не подгоняя его заведомо под рамки ООП. Называя вещи своими именами — дать ООП роль "низкоуровневого" инструмента, призванного обеспечивать наш "высокоуровневый" взгляд на вещи. Тоже самое касается чистого ФП — это всё низкоуровневые подробности реализации.


S>Встречный вопрос. глубокий предварительный анализ потоков данных не препятствует итеративной разработке с уточнением требований?


Нет. Речь шла о хоть каком-то анализе алгоритмов и данных vs проектирование от квадратиков. И там и там на кончике карандаша всю систему разработать проблематично, но первая модель будет ближе к реально происходящему уже на первой итерации. У тебя будет банально больше информации в первом случае, чтобы нарисовать более удачный вариант квадратиков.


S>Потому встречный вопрос — что требовать и спрашивать (что бы потенциальный профессионал не ушел к конкуренту)?


Если так ставить вопрос — то ничего.
Я же говорю — дефицит вменяемой программистской рабсилы. ИМХО, спросить можно, на сколько он хочет пополнить свои знания в сравнении с сегодняшним уровнем. Або я встречал "спецов", которые неплохо владеют языками, фактически на уровне дословного знания спецификаций, но полны различных предрассудков, с которыми тяжело бороться. Приходится заставлять писать тестовые примеры, дабы лечить от предрассудков. А перед этим еще приходится объяснять, почему надо писать эти "нелепые" примеры...


S>Проблема такого подхода в том, что каждый добавляющий функциональность, думает что он последний. Последующему приходится погружаться в более нагроможденный код.


Практика комментирования коммитов и щедрость на TODO помогает упорядочивать. Главное, чтобы команда преследовала общие цели, и если кто-то видит, что образуется потенциально слабое место — поставил сигнальный флажок на нем.

V>>Они и так сами получаются. Деление на слои процесс как бы автоматический, управляется сложностью единичного элемента, которую может обозреть человек. Какое там правило для ф-ий и методов — не больше 1-2 экранов кода? Примерно так.

S>Автоматический для тех кто уделяет этому достаточно внимания

Всё-равно автоматически по достижении некоторого порога. Однажды становится трудно просто прочесть код, даже если он хорош. И единственно правильное решение — декомпозировать, передокументировать и прочесть заново. Это может сэкономить часы и это дополнительный review кода. Оно как эффект катастрофы в природе, во вменяемой команде выполняется на автомате всеми участниками.
Re[10]: Почему объектно-ориентированное программирование про
От: vdimas Россия  
Дата: 21.02.11 08:59
Оценка:
Здравствуйте, FR, Вы писали:

V>>Ты не самый интересный момент комментируешь. Суть этих постов была в замеченном факте, что давая больше доступа к обрабатываемым данным во внутреннем АПИ, надобность структурного рефакторинга, того самого, когда заметно меняется состав объектов и еще более заметно их роли, почти всегда выходит ниже.


FR>Кстати функциональщина как раз поощряет (АТД и ПМ) такой больший доступ.


Да там способа другого нет. Это позволило обнаружить рассматриваемую полезную практику, ведь ничто не мешает перетащить ее в ООП.
Re[9]: Почему объектно-ориентированное программирование пров
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 21.02.11 09:29
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Что касается больших проектов, ИМХО, пока спасает только компонентное программирование.


КОП и ООП в мейнстриме тесно связаны.

V> И твое высказываемое наблюдение, что в больших иерархиях удобнее реализовывать интерфейсы, а не наследовать реализации, тому пример. Это же КОП чистой воды.


Конечно же нет. Во-первых реализация интерфейсов нужна исключительно для полиморфизма, что к КОП имеет весьма опосредованное отношение. Во-вторых дело далеко не в удобстве, я это стопицот раз уже писал.

V> Хотя сей способ на иерархиях среднего размера, скажем прямо, себя не окупает — не тот уровень распараллеливания работы по людям и по собственным мозгам.


Вот так вот прям всегда и везде? Однако.

AVK>>Рефакторинг и анализ не противоречат друг другу, непонятно с чего ты их противопоставляешь.


V>Второй раз похожее замечание... Наверно от того, что весь рефакторинг был свален в одну кучу. В общем, речь шла не только о рефакторинге, но и об откровенных переделках.


Какие то очень размытые термины и неуместная генерализация. Размер и проблемность рефакторинга в большей степени зависит от частоты проведения рефакторинга и вообще отношения к качеству кода, а не от количества свободных функций и классов.

V>Теперь по теме. ИМХО, рефакторинг/переделки, вызванные пересмотром состава и ролей объектов, связан(ы) обратно с уровнем проведенного анализа.


Т.е. ты считаешь, что если хорошо проанализировать, то можно с первой итерации создать финальный детальный дизайн приложения?

V>Но первый случай может быть очень болезненным, т.к. может требовать заметной трудоемкости по обеспечению безопасности операций над обновленным множеством инкапсулированных состояний.


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

V>>>Может так оказаться, что это была последняя добавленная функциональность в класс, и нафига тогда делать работу, которую никто не оценит?

AVK>>Стремный очень подход, как на мой вкус.

V>Практичный


Практичный он только на очень коротких временных интервалах. Либо на специфичных проектах, где код модифицируется редко. На моем опыте почему то вся на первый взгляд безобидная халява обязательно вылазит в виде граблей позже.

V>Ты не самый интересный момент комментируешь. Суть этих постов была в замеченном факте, что давая больше доступа к обрабатываемым данным во внутреннем АПИ, надобность структурного рефакторинга, того самого, когда заметно меняется состав объектов и еще более заметно их роли, почти всегда выходит ниже.


Мои замечания относятся к исходным предпосылкам. Поскольку они неверны, то вывод, как минимум, необоснован. И да, на практике я замечаю прямо противоположное — чем меньше связность кода, тем проще, легче и безболезненнее рефакторинг.
... << RSDN@Home 1.2.0 alpha 5 rev. 1495 on Windows 7 6.1.7600.0>>
AVK Blog
Re[7]: Почему объектно-ориентированное программирование пров
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 21.02.11 09:29
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Зло здесь проявляется лишь в обязательности рефакторинга в ООП по мере роста сложности программы.


Рефакторинг, конечно, не обязателен. Но крайне желателен, независимо от того, ООП это, ФП или структурное программирование в чистом виде.

V> Это банально мешает при совместной разработке.


Куда больше мешает деградация качества кода при отсутствии рефакторинга.
... << RSDN@Home 1.2.0 alpha 5 rev. 1495 on Windows 7 6.1.7600.0>>
AVK Blog
Re[3]: Почему объектно-ориентированное программирование пров
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 21.02.11 10:30
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Нужен меньше. По опыту плюсов, чем меньше создаешь классов, т.е. чем больше функциональности удается разнести в свободные ф-ии, тем меньше надобность рефакторинга.


И наоброт — чем больше функциональности в свободных функций, тем сильнее нужен рефакторинг, например из за того, что слишком много функций зависит от одного класса.

>ИМХО, это объяснимо, т.к. объект в ООП — это группировка в "одно целое" относительно большого кол-ва элементов программы. И весь рефакторинг, по-сути, это перетасовка элементов таких групп.


Как то ты странно ООП понимаешь

>Пройдись по формальным методам рефакторинга: 90% рефакторинга — это способы перемещения методов и полей м/у объектами таким образом, чтобы не поломать случайно исходное поведение программы.


Ты вероятно Фаулера читал Рефакторинг это реорганизация обязанностей и зависимостий при сохранении НАБЛЮДАЕМОГО поведения программы.

Если ты понаписывал много свободных функций и оставил мало функциональности в классе, то это вовсе не значит, что рефакторинг не нужен. Зависимости ведь реально никуда не делись и обязанности тож

Соответственно при изменении требований выявляются проблемы — изменил класс, измени и сотню свободных фунций. Все, приехали.
Re[4]: Почему объектно-ориентированное программирование пров
От: FR  
Дата: 21.02.11 10:40
Оценка: 18 (1) +1
Здравствуйте, Ikemefula, Вы писали:

V>>Нужен меньше. По опыту плюсов, чем меньше создаешь классов, т.е. чем больше функциональности удается разнести в свободные ф-ии, тем меньше надобность рефакторинга.


I>И наоброт — чем больше функциональности в свободных функций, тем сильнее нужен рефакторинг, например из за того, что слишком много функций зависит от одного класса.


Не нужен, такие классы ничего лишнего не содержат и их внешний интерфейс менять практически не приходится, зато рефакторить внутренности таких классов намного легче Как функции, не являющиеся методами, улучшают инкапсуляцию
Re[5]: Почему объектно-ориентированное программирование пров
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 21.02.11 10:45
Оценка:
Здравствуйте, vdimas, Вы писали:

V>А по существу... Не проблема преобразовать. Проблема в том, что дается механизм, достаточно легкий для дизайна "верхнего уровня", который практически сразу позволяет набросать основной скелет программы и всё выходит красивым и очевидным. Это ООП, и это его несомненное достоинство. От этого трудно отказаться, поэтому это используют. Не зря коллеги говорят, что дизайн верхнего уровня в ООП смотрится лучше всего. Так в чем засада? ИМХО, проблемы в ООП начинаются там, где объекты начинают "тяжелеть", а иерархии разрастаться. А они это делают не потому что кто-то дурак, а по объективным мотивам: уточняется функциональность, растет список сценариев и т.д. Что мы делаем в ответ на разбухание кода? Мы вводим новые "слои" в наш ООП, выделяем "хелперы" и целые "независимые подсистемы" и так до бесконечности. Вот что имелось ввиду, когда утверждалось, что ООП обречен на постоянный рефакторинг, то бишь на постоянное переписывание кода.


Рефакторинг это _не_ переписывание.

"Мы вводим новые "слои" в наш ООП, выделяем "хелперы" и целые "независимые подсистемы" и так до бесконечности."

Конечно, не у каждого есть видение самого конечного дизайна. Скажем если потратил на ООП-решение год, то это вовсе не означает, что на ФП ты сходу выдашь точно такое же или лучшее.

V>При большом объеме функционала нужно что-то легковесное, чтобы была возможность легко и непринужденно этой функциональностью ворочать, без рефакторинга на каждый чих. В ФП нет возможности вот так красиво описать статическую структуру участников. фП думает от данных и потоков их обработки. Им всю программу приходится писать в терминах "хелперов" и "подсистем" с самого начала. Плюс продумывать тщательно, как "протаскиваются" эти данные и прочий контекст в процессе вычисления. Вот и выходит, что по мере роста функционала им ничего переписывать не приходится, всё уже переписано с самого начала и заведомо декомпозировано до уровня плинтуса. В отличие от "черных ящиков" ООП.


Это так кажется. Код всегда можно улучшить. Хоть ФП, хоть ООП. Рефакторинг это один из способов улучшения кода, инструмент решения проблем.

V>Справедливости ради, в ООП тоже сей подход можно использовать. Т.е. брать у ФП не только модную здесь иммутабельность и замыкания (порой до экстаза), но саму программу плясать от данных и небольших объектов, представляющих эти данные с одной стороны, и осуществляющие обработку этих данных с другой стороны. Заметь, это отход от парадигмы общепринятой парадигмы ООП, хотя используются ООП ср-ва. Итоговый дизайн должен представлять из себя большое кол-во легковесных объектов минимальнейшей функциональности, которые не потребует рефакторинга ни при каких обстоятельствах. ИМХО, такой стиль — дело привычки.


SOLID — это и есть ООП Правильно распознать все обязанности, зависимости, провести границу детализации — это не дело привычки, это адский труд.
Re[9]: Почему объектно-ориентированное программирование пров
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 21.02.11 10:48
Оценка: +1
Здравствуйте, vdimas, Вы писали:

V>Ты не самый интересный момент комментируешь. Суть этих постов была в замеченном факте, что давая больше доступа к обрабатываемым данным во внутреннем АПИ, надобность структурного рефакторинга, того самого, когда заметно меняется состав объектов и еще более заметно их роли, почти всегда выходит ниже.


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

Про это написано практически во всх книгах по рефакторингу — Фаулер, Физерс, Кент Бек, Кериевск и тд.
Re[5]: Почему объектно-ориентированное программирование пров
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 21.02.11 11:18
Оценка:
Здравствуйте, FR, Вы писали:

I>>И наоброт — чем больше функциональности в свободных функций, тем сильнее нужен рефакторинг, например из за того, что слишком много функций зависит от одного класса.


FR>Не нужен, такие классы ничего лишнего не содержат и их внешний интерфейс менять практически не приходится, зато рефакторить внутренности таких классов намного легче


То есть, если надо внести изменения в этот класс, то функции сами собой перепишутся ?

Или менять функции никогда не придется ?

Никакой SOLID не отменяет необходимости рефакторинга Ну разве что сразу взять да написать идеально с учетом требований на 100 лет вперёд.
Re[10]: Почему объектно-ориентированное программирование про
От: vdimas Россия  
Дата: 21.02.11 12:25
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>КОП и ООП в мейнстриме тесно связаны.


В плюсах КОП в чистом виде накладен.


V>> И твое высказываемое наблюдение, что в больших иерархиях удобнее реализовывать интерфейсы, а не наследовать реализации, тому пример. Это же КОП чистой воды.


AVK>Конечно же нет. Во-первых реализация интерфейсов нужна исключительно для полиморфизма, что к КОП имеет весьма опосредованное отношение.


Тем не менее, полиморфизм в КОП так же доступен и используется так же. И вопрос ради любопыства: у тебя никогда не бывает так, что некий интерфейс реализован лишь однажды? Именно в production, не учитывая тестовых реализаций? (бо для тестовых случаев есть другие техники)


AVK>Во-вторых дело далеко не в удобстве, я это стопицот раз уже писал.


А что есть "удобство" в плане разработки/поддержания ПО, как не снижение суммарной трудоемкости?


V>> Хотя сей способ на иерархиях среднего размера, скажем прямо, себя не окупает — не тот уровень распараллеливания работы по людям и по собственным мозгам.


AVK>Вот так вот прям всегда и везде? Однако.


Угу, "всегда и везде" это конечно сильно, не возразишь. Тем не менее, "полу-абстрактные" классы (в которых не все методы абстрактны) по-прежнему эффективны и активно используются в заметных по размеру иерархиях того же дотнета.

AVK>Размер и проблемность рефакторинга в большей степени зависит от частоты проведения рефакторинга и вообще отношения к качеству кода, а не от количества свободных функций и классов.


От количества связей проблемность больше зависит. Иногда "простой" рефакторинг базовой функциональности может потянуть за собой много изменений, не поддающихся автоматическому рефакторингу, в "клиентском" месте использования. Например, как произошло с некоторыми коллекциями для SL в сравнении с обычным .Net FW.

V>>Теперь по теме. ИМХО, рефакторинг/переделки, вызванные пересмотром состава и ролей объектов, связан(ы) обратно с уровнем проведенного анализа.


AVK>Т.е. ты считаешь, что если хорошо проанализировать, то можно с первой итерации создать финальный детальный дизайн приложения?


Было сказано "более удачный". Речь шла о выявлении наиболее частоупотребимых сценариев на уровне анализа, сие помогает выявить функциональность с наибольшим повторным использованием. И это нужно для меньшей болезненности описанного абзацем выше.


V>>Но первый случай может быть очень болезненным, т.к. может требовать заметной трудоемкости по обеспечению безопасности операций над обновленным множеством инкапсулированных состояний.


AVK>Опять ты чего о путаешь. Подобные проблемы возникают исключительно из-за низкого качества кода, типа большого количества тяжелых изменяемых состояний. И, сюрпрайз, наследование реализаций это одна из тех вещей, которая этому (проблемам с рефакторингом) способствует.


Тяжелые изменяемые состояния, да еще транзакционно изменяемые, могут быть частью предметной области. И это мы еще не договорились, что есть тяжелые, а что нет. По мне, проблема — это когда вокруг обсуждаемого состояния очень много функциональности. Т.е. проблемы по связанности начинаются уже внутри объекта, а не за его пределами. а этой функциональности может быть много просто по характеру предметной области. Тогда такое состояние стоит выносить из инкапсуляции, делать безопасный интерфейс именно к состоянию и рассматривать его как данные. А если даже состояние "большое", но по нему пару операций — это обычно не проблема. Даже для последующего рефакторинга. В общем, проблемой считаю большое кол-во кол-во изменений в коде, связанных с небольшим изменением композиции состояний. Это даже через интерфейсы может задеть многое, из-за надобности сии интерфейсы корректировать.


AVK>Практичный он только на очень коротких временных интервалах.


Недельный цикл разработки — это "долго"? Про ситуацию с блокерами уже делал замечание. Собсно, на них такое и происходит. Но это не повод, всё бросать и тут же переделывать, особенно если над тем же кодом работает/использует 5 и более человек.


AVK>Либо на специфичных проектах, где код модифицируется редко.


Не редко, а упорядоченно. Т.е. не одновременно с активной разработкой, чтобы не тратить по часу на ручной мерж веток.


AVK>На моем опыте почему то вся на первый взгляд безобидная халява обязательно вылазит в виде граблей позже.


Ну, пока все TODO в исходниках не закрыты, сдавать код никто не будет. Конечно, без некоей культуры совместной разработки никуда. Но это не только рефакторинга касается.


V>>Ты не самый интересный момент комментируешь. Суть этих постов была в замеченном факте, что давая больше доступа к обрабатываемым данным во внутреннем АПИ, надобность структурного рефакторинга, того самого, когда заметно меняется состав объектов и еще более заметно их роли, почти всегда выходит ниже.


AVK>Мои замечания относятся к исходным предпосылкам. Поскольку они неверны, то вывод, как минимум, необоснован.


Я пока не увидел, насчет "неверны". Тяжелые состояния, низкое качество кода и т.д. — требует определения.

По мне, низкое качество кода, это такое, которое для удовлетворения всех функциональных и нефункциональных требований к нему потребует значительной переделки/рефакторинга как в нем так и по зависимостям. И через непродуманные интерфейсы в т.ч. По сути, практически весь недописанный код некачественный. Т.е. метрика степени его некачественности — это суммарное кол-во телодвижений, требуемых до доведения до качественного.

Остальное, типа читабельности, "красоты" и прочее доводиться локально без каких-либо дерганий окружения, по сему мало волнует. Даже переименование, задевающее сотни мест использования, не составляет никакой проблемы. Ручного-то вмешательства не требуется. А читабельность и так доводится в процессе взаимного ревью. ИМХО, "читателями" лучше всего и доводится.


AVK>И да, на практике я замечаю прямо противоположное — чем меньше связность кода, тем проще, легче и безболезненнее рефакторинг.


Правильно, я высказывал мысли, как этого достичь в полуавтоматичном режиме. Выделяя некое состояние как "данные", мы фиксируем безопасный "интерфейс" доступа к данным, оставляя на свободе функционал вокруг них. И вот это множество, составляющее функционал, само по себе выходит слабо м/у собой связанным. Дело в том, что полно ситуаций, когда набор данных меняется редко (не путать с добавлением других данных), а вот операции, даже по устаканенным данным, пересматриваются/уточняются часто. Рефакторинг, связанный с декомпозицией состояния объектов (например, поля тусуем из наследников в базу и обратно или в другой агрегированный объект) по моему наблюдению вызывается развитием именно функциональности. И вот для удовлетворения этого развития нам одни и те же инкапсулированные данные становятся нужны в разных местах, где ранее их надобность не представлялась очевидной. Или наоборот, новая "маленькая" функциональность объекта требует для своей работы как всё остальное состояние, так и еще пару, нужных только для нее, полей. После нескольких таких добавлений требуется переделка. Это обычные происходящие в разработке вещи, именно они и приводят к последующему рефакторингу с пересмотром инкапсуляции. Потому и предлагалось, в расширение обычной практики, посмотреть на вариант, не будет ли удобным часть состояний сразу рассматривать как данные/контекст и т.д. А это без списка сценариев и предварительной прикидки алгоримов по ним не угадаешь.
Re[6]: Почему объектно-ориентированное программирование пров
От: vdimas Россия  
Дата: 21.02.11 12:38
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Конечно, не у каждого есть видение самого конечного дизайна. Скажем если потратил на ООП-решение год, то это вовсе не означает, что на ФП ты сходу выдашь точно такое же или лучшее.


Конечно не выдашь. Я лишь делюсь, как удается использовать большее кол-во наработок без переделки.

V>>При большом объеме функционала нужно что-то легковесное, чтобы была возможность легко и непринужденно этой функциональностью ворочать, без рефакторинга на каждый чих. В ФП нет возможности вот так красиво описать статическую структуру участников. фП думает от данных и потоков их обработки. Им всю программу приходится писать в терминах "хелперов" и "подсистем" с самого начала. Плюс продумывать тщательно, как "протаскиваются" эти данные и прочий контекст в процессе вычисления. Вот и выходит, что по мере роста функционала им ничего переписывать не приходится, всё уже переписано с самого начала и заведомо декомпозировано до уровня плинтуса. В отличие от "черных ящиков" ООП.


I>Это так кажется. Код всегда можно улучшить. Хоть ФП, хоть ООП. Рефакторинг это один из способов улучшения кода, инструмент решения проблем.


Повторю — требуется нечто легковесное, когда требуется ворочать большим накопленным функционалом. Именно для того, чтобы не бояться играть дизайном верхнего уровня, беспокоясь что все остальное отлетит. Конечно, без развития дизайна никуда. Вопрос в том, чтобы это развитие сделать максимально дешевым. Кто-то тут настаивает на постоянном рефакторинге. Ну что же, если есть для используемого языка хороший тул по рефакторингу, возможно, что это вариант. Хотя на C# сия легковесность тоже прекрасно работает с тем же эффектом.

I>SOLID — это и есть ООП Правильно распознать все обязанности, зависимости, провести границу детализации — это не дело привычки, это адский труд.


Но ведь не факт, что в первой итерации будет удачно, правильно? Почему бы начинать не с максимально закрытой инкапсуляции, а местами с открытой, закрывая потом частности по мере устаканивания собственного видения происходящего? Еще раз, объектная декомпозиция — это практически всегда разделение состояния, т.е. ухудшение инкапсуляции, т.е. всё больше подробностей реализации начинает торчать наружу, да еще добавляются обвески в плане того, что новые объекты должны "правильно" друг друга использовать. Вот эти меняющиеся информационные составляющие, да еще когда 90% из них временны и живут лишь до следующей переделки/рефакторинга — тоже немалая часть балласта в период разработки.
Re[4]: Почему объектно-ориентированное программирование пров
От: vdimas Россия  
Дата: 21.02.11 13:00
Оценка:
Здравствуйте, Ikemefula, Вы писали:


>>ИМХО, это объяснимо, т.к. объект в ООП — это группировка в "одно целое" относительно большого кол-ва элементов программы. И весь рефакторинг, по-сути, это перетасовка элементов таких групп.


I>Как то ты странно ООП понимаешь


Не само ООП, а связь ООП с рефакторингом.

>>Пройдись по формальным методам рефакторинга: 90% рефакторинга — это способы перемещения методов и полей м/у объектами таким образом, чтобы не поломать случайно исходное поведение программы.


I>Ты вероятно Фаулера читал Рефакторинг это реорганизация обязанностей и зависимостий при сохранении НАБЛЮДАЕМОГО поведения программы.


Фаулера терпеть ненавижу.
Пройдись по формальному описанию методов рефакторинга для C#.


I>Если ты понаписывал много свободных функций и оставил мало функциональности в классе, то это вовсе не значит, что рефакторинг не нужен. Зависимости ведь реально никуда не делись и обязанности тож


Было наоборот сказано, что нужно нечто, чем можно "легко ворочать". Т.е. развитие дизайна — это нормально, речь о суммарном количестве связанных с этим телодвижений.


I>Соответственно при изменении требований выявляются проблемы — изменил класс, измени и сотню свободных фунций. Все, приехали.


Это смотря что мы изменяем: данные, или функционал. Вот тут подробней: http://rsdn.ru/forum/philosophy/4166957.1.aspx
Автор: vdimas
Дата: 21.02.11


Если заметно меняются данные, то изменения будут во всех задевающих их ф-иях, независимо от того, свободные они, или являются методами объектов. А вот при доработке функциональности по имеющимся данным — картинка уже совсем другая.

Обрати внимание, как неплохо вписались методы-расширения в C# и с каким удовольствием народ это использует. Потребуется ли тебе рефакторинг таких методов расширения из нейспейса, например, Linq? "А с какой стати?", ты спросишь, и будешь прав, ибо необходимые себе методы-расширения ты можешь нарисовать "рядом", не вступая в конфликт с имеющимся. В общем, это примерно то, о чем так долго говорила Коммунистическая Партия. (С) Глобальные ф-ии отбрасывать не стоит. Ну а по замыканиям и прочим ф-ным объектам мы уже проходились тут неоднократно.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.