Здравствуйте, MozgC, Вы писали:
MC>А почему вы считаете что ответственность класса Order это только держать данные для заказа? Так можно начать про что угодно говорить. Давайте скажем что ответственность класса String — держать набор символов, а все методы нужно вынести в хелперный класс (сервис) и будет у нас StringService.GetStringLength(), StringService.IndexOf(), StringService.StringToUpper() и т.д.
Кстати, именно так Александреску и советует делать для С++, где изобретение собственных строк — это народная забава.
Здравствуйте, Ziaw, Вы писали:
AVK>>Если у тебя в публичном интерфейсе OrderLines есть метод Add — AddOrderLine следует вынести в dev/null Z>А то, что он сделан таким для совместимости с ORM — в топку ORM?
Да, так как это плохой ORM.
Здравствуйте, Ziaw, Вы писали:
Z>Какие рекомендации будут по замене ORM? Полный отказ, поиск, покупка и освоение ORM который сможет работать с правильным контрактом или написание своего?
Тот же Hibernate нормально с подчинёнными коллекциями работает.
Z>Может я не вижу очевидного решения которое не затормозит разработку на несколько человекомесяцев и будет удовлетворять всем канонам дизайна?
А поправить сам ORM нельзя?
Здравствуйте, IB, Вы писали:
IB>Здравствуйте, stump, Вы писали:
S>>Мне? Здравый смысл. IB>Ну, собственно, с чего начали — наш формальный критерий называется "здравый смысл". Я не отрицаю, штука полезная, но на формальный критерий не тянет никак.
Кому нужны формальные критерии? Да и топикстартер не спрашивал про формальные критерии. В программировании есть множество формальных критереев, которые совсем необъективны.
Формальные критерии — не результат, а только материал для анализа.
S>>А на мой взгляд — нет. IB>То есть, все возражения свелись к мелкому неудобству при использовании.
Каждое мелкое неудобство в использовании рано иили поздно становится ошибкой в программе.
S>>У тебя есть заклинание "только через публичный контракт" IB>Это не заклинание, это фактор который ты упорно игнорируешь. За всю дискуссию ты не привел ни одного возражения, просто молча пропускал, поэтому я вынужден был повторять это снова и снова.
Заклинание "только через публичный контракт" плохо работает для эволюционного проектирования.
"только через публичный контракт" иногда может сильно повлиять на быстродействие.
"только через публичный контракт" не стоит применять для методов, изменяющих состояние объекта. Не знаю как вы, а я сильно удивляюсь если вызов A.B(x) меняет состояние x.
Здравствуйте, gandjustas, Вы писали:
G>Кому нужны формальные критерии?
Прочитав топик, не сложно убедиться, что мой оппонент утверждал, что его критерий нужно помещать метод в код или нет — чудо как четок и формален. Как выяснилось он ошибался.
G>Да и топикстартер не спрашивал про формальные критерии.
Он — нет, но дискуссия развернулась именно в этом направлении.
G> В программировании есть множество формальных критереев, которые совсем необъективны.
Это не имеет отношения к данному обсуждению.
G>Формальные критерии — не результат, а только материал для анализа.
В данном случае, формальный критерий — результат очень тщательного анализа.
G>Каждое мелкое неудобство в использовании рано иили поздно становится ошибкой в программе.
Не буду топтаться на этом, весьма спорном тезисе, замечу только, что погоня за удобствами ведет к куда большим ошибкам.
G>Заклинание "только через публичный контракт" плохо работает
Заклинания вообще плохо работают, за заклинаниями не ко мне.
G> для эволюционного проектирования.
Доказательства будут?
G>"только через публичный контракт" иногда может сильно повлиять на быстродействие. G>"только через публичный контракт" не стоит применять для методов, изменяющих состояние объекта. G>Не знаю как вы, а я сильно удивляюсь если вызов A.B(x) меняет состояние x.
У меня ощущение, что ты не очень внимательно прочитал топик и сильно попутал о чем речь.
Напомню еще раз: Речь не о том, что бы во что бы то ни стало работать через публичный контракт (хотя по возможности надо стараться пользоваться именно публичным контрактом), а о том, что если метод работает с классом через публичный контракт, то он должен находиться вне класса.
Здравствуйте, IB, Вы писали:
IB>Здравствуйте, gandjustas, Вы писали:
G>>Кому нужны формальные критерии? IB>Прочитав топик, не сложно убедиться, что мой оппонент утверждал, что его критерий нужно помещать метод в код или нет — чудо как четок и формален. Как выяснилось он ошибался.
Формальность и объективность не одно и тоже.
G>>Формальные критерии — не результат, а только материал для анализа. IB>В данном случае, формальный критерий — результат очень тщательного анализа.
Одно другому не мешает.
G>>Каждое мелкое неудобство в использовании рано иили поздно становится ошибкой в программе. IB>Не буду топтаться на этом, весьма спорном тезисе, замечу только, что погоня за удобствами ведет к куда большим ошибкам.
Не надо гнаться за удобством, но и жертвовать удобством в счет "правильности" тоже не лучшее решение.
G>> для эволюционного проектирования. IB>Доказательства будут?
При эволюционном проектировани публичные контракты могут меняться достаточно часто.
G>>"только через публичный контракт" иногда может сильно повлиять на быстродействие. G>>"только через публичный контракт" не стоит применять для методов, изменяющих состояние объекта. G>>Не знаю как вы, а я сильно удивляюсь если вызов A.B(x) меняет состояние x. IB>У меня ощущение, что ты не очень внимательно прочитал топик и сильно попутал о чем речь. IB>Напомню еще раз: Речь не о том, что бы во что бы то ни стало работать через публичный контракт (хотя по возможности надо стараться пользоваться именно публичным контрактом), а о том, что если метод работает с классом через публичный контракт, то он должен находиться вне класса.
Этот тезис не противоречит вызовам A.B(x), менящюим x.
Здравствуйте, minorlogic, Вы писали:
M>Следуя твоей логике наименьшая связанность будет у программы с main и одним классом/функцией. Очевидный для меня абсурд.
Ну угадал. Локальные функции рулят Может Хейлсберг когда-нибудь родит что-нибудь подобное в шарпе.
Неясность изложения обычно происходит от путаницы в мыслях.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IB, Вы писали:
IB>Здравствуйте, gandjustas, Вы писали:
Несколько замечаний не по предмету, а по ходу дискуссии.
G>>Кому нужны формальные критерии? IB>Прочитав топик, не сложно убедиться, что мой оппонент утверждал, что его критерий нужно помещать метод в код или нет — чудо как четок и формален. Как выяснилось он ошибался.
Это выяснилось только лишь для тебя. Дело в том что я говорил о множестве критериев, как в пользу выноса функции из класса, так и в пользу помещения ее в класс. Большинство из них просто выпало из обсуждения благодаря твоей забавной манере вести дискуссию. Ты усиленно опровергаешь все, что противоречит твоей точке зрения, а на остальное просто не обращаешь внимания. G>>Да и топикстартер не спрашивал про формальные критерии. IB>Он — нет, но дискуссия развернулась именно в этом направлении.
Поэтому дискуссия и равернулась в данном направлении. G>> В программировании есть множество формальных критереев, которые совсем необъективны. IB>Это не имеет отношения к данному обсуждению.
Именно это и обсуждается сейчас. G>>Формальные критерии — не результат, а только материал для анализа. IB>В данном случае, формальный критерий — результат очень тщательного анализа.
Многие уже привели примеры когда твой формальный критерий не работает.
G>> для эволюционного проектирования. IB>Доказательства будут?
Были уже. Потрудись перечитать аргументацию оппонентов. G>>"только через публичный контракт" иногда может сильно повлиять на быстродействие. G>>"только через публичный контракт" не стоит применять для методов, изменяющих состояние объекта. G>>Не знаю как вы, а я сильно удивляюсь если вызов A.B(x) меняет состояние x. IB>У меня ощущение, что ты не очень внимательно прочитал топик и сильно попутал о чем речь. IB>Напомню еще раз: Речь не о том, что бы во что бы то ни стало работать через публичный контракт (хотя по возможности надо стараться пользоваться именно публичным контрактом), а о том, что если метод работает с классом через публичный контракт, то он должен находиться вне класса.
Увы, но убедительного обоснования этого тезиса так и не прозвучало.
Здравствуйте, IB, Вы писали:
IB>Да прямее уже и не найдешь. Обсуждаемые хелперы — DI сервисы в чистом виде.
Injection означает то, что зависимости задаются снаружи, а не прибиты гвоздями как статик хелпер.
Хотя с определенного уровня абстракции можно увидеть признаки "DI времени кодирования" .
Z>>они все проектировали так, чтобы людям было удобнее ее использовать. IB>То есть, единственное возражение "не удобно использовать"?
Собственно да. Мне нравится идеология базовых библиотек ruby. Я знаю, что практически все что мне нужно сделать с объектом я сделаю с помощью его собственных методов. Чаще всего в конвеерном стиле цепочки вызовов. Возможно у меня дурной вкус, но я рад, что C# 3.0 дает мне возможность делать похожий дизайн.
Я согласен с тем, что код оперирующий лишь публичным контрактом можно вынести в отдельный модуль.
Я согласен с тем, что в C# 3.0, при использовании extension methods это можно делать для любого такого метода (в ruby кстати тоже).
Я согласен с тем, что это может удешевить поддержку продукта.
Я категорически не согласен с тем, что "нет разницы между вызовом экземплярных методов и методов статик хелперов".
Я не согласен с тем, что удобством использования класса можно пренебречь при его проектировании.
Здравствуйте, C...R...a...S...H, Вы писали:
CRA>Здравствуйте, stump, Вы писали:
S>>Теперь, если кто умеет, посчитайте метрики связности кода для случая с классом OrderCalcHelper и без него. CRA>Очень мне было интересно, прикинуть метрики. Вот результат расчета VS2008: CRA>С Helper'ом CRA>Namespace: Test CRA>Maintainability Index: 93 CRA>Cyclomatic Complexity: 19 CRA>Depth of Inheritance: 1 CRA>Class Coupling: 7 CRA>Lines of Code: 22
CRA>Без Helper'а CRA>Namespace: Test CRA>Maintainability Index: 92 CRA>Cyclomatic Complexity: 18 CRA>Depth of Inheritance: 1 CRA>Class Coupling: 6 CRA>Lines of Code: 21
CRA>Получается по расчетам VS, сопровождаемость программы с Helper'ом лучше чем без него
на 1 процентный пункт.
Без хелпера связность 6, с хэлпером связность 7. В примере хэлпер увеличил связность на 17%. Что и требовалось доказать.
Здравствуйте, gandjustas, Вы писали:
G>Формальность и объективность не одно и тоже.
Еще раз повторить? Оппонент утверждал, что его критерий формален — выяснилось, что ни разу.
Что здесь не объективного?
G>Одно другому не мешает.
И что ты хочешь этим сказать?
G>Не надо гнаться за удобством, но и жертвовать удобством в счет "правильности" тоже не лучшее решение.
В данном случае "правильность" не абстрактна и может быть выражена совершенно конкретными циферками, в чем легко убедиться опять-таки внимательно прочитав топик.
G>При эволюционном проектировани публичные контракты могут меняться достаточно часто.
Тогда наоборот, такой подход изумительно подходит для эволюционного проектирования, так как помимо всего прочего еще и компилятор следит за тем, что публичный контракт поменялся, а тот кто им пользуется — еще нет.
G>Этот тезис не противоречит вызовам A.B(x), менящюим x.
Ты любой код меняющий x помещаешь в x? UI например? Надеюсь, все таки нет... Правильный вызов будет выглядет так: var newX = A.B(oldX);
Здравствуйте, stump, Вы писали:
S>Это выяснилось только лишь для тебя.
Это выяснилось для всех, кто дал себе труд внимательно прочитать топик. Ни одного строгого критерия ты так и не привел, все ограничилось здравым смыслом. Я, безусловно, не отрицаю его пользу, но перефразируя классику, здравым смыслом и формальным критерием можно добиться гораздо большего, чем просто здравым смыслом.
S>Дело в том что я говорил о множестве критериев, как в пользу выноса функции из класса, так и в пользу помещения ее в класс.
Ты совершенно четко сказал, что у тебя есть чудо как формальный критерий позволяющий определить вносить функцию в класс или нет, но сформулировать его ты так и не смог.
S> Большинство из них просто выпало из обсуждения благодаря твоей забавной манере вести дискуссию.
После того как аргументы кончились, ты начинаешь ссылаться на мою манеру ведения дискуссии. Я, кстати, не первый это замечаю.
Не находишь, что если с манерой что-то не так, то наверное все-таки не у меня?
Я, конечно, бываю временами несколько резок, но только если оппонент совсем пургу несет или занимается откровенной демагогией.
S> Ты усиленно опровергаешь все, что противоречит твоей точке зрения, а на остальное просто не обращаешь внимания.
Это упрек? Очевидно я буду опровергать то, что не соответствует моей точке зрения и спокойно пропускать все остальное, так как это поддерживает мою позицию.. При этом я вполне поддаюсь убеждению, если аргументы здравые и внятные.
В данном случае, на протяжении всей дискуссии, был только один относительно внятный контраргумент — "некоторым неудобно использовать".
S>Именно это и обсуждается сейчас.
Какое отношение другие формальные критерии в CS, имеют отношение к данному конкретному критерию?
S>Многие уже привели примеры когда твой формальный критерий не работает.
Да ты что?! Где? Ни одного примера не было приведено, ни тобой, ни другими участниками дискуссии.
S>Были уже. Потрудись перечитать аргументацию оппонентов.
Не было. Я очень внимательно читаю весь топик. Вся аргументация оппонентов свелась к "пользуйтесь здравым смыслом" и "неудобно использовать".
S>Увы, но убедительного обоснования этого тезиса так и не прозвучало.
Прозвучали более чем убедительные доказательства, как на словах, так и с отсылкой на классиков. То что они тебе не нравятся, уже не моя вина.
Здравствуйте, stump, Вы писали:
S>на 1 процентный пункт.
Так там и кода на наперсток.
S>Без хелпера связность 6, с хэлпером связность 7.
Ты все напутал, не "связность", а "связь между классами". Тебе еще раз определение связности привести?
S>Что и требовалось доказать.
В итоге ты доказал ровно обратное. Главная метрика — это как раз индекс поддерживаемости. Большая связность, в конечном итоге, плоха именно плохой поддерживаемостью, и именно это тебе студия и насчитала.
Здравствуйте, Ziaw, Вы писали:
Z>Injection означает то, что зависимости задаются снаружи, а не прибиты гвоздями как статик хелпер.
Так никто и не призывает оставлять статик хелпер. Я уже расписывал, как происходит эволюция кода вынесенного за приделы класса, в конечном итоге он перерождается в полноценный DI сервис, умеющий работать с семейством объектов, из которого его изначально вынесли.
Очень способствует и гибкости, и удобству поддержки, и повторной используемости кода.
Z>Хотя с определенного уровня абстракции можно увидеть признаки "DI времени кодирования" .
Это просто промежуточный рефакторинг, помогающий перейти от захардкоженного в класс функционала к DI.
IB>>То есть, единственное возражение "не удобно использовать"? Z>Собственно да.
Уфф..
Z>Я знаю, что практически все что мне нужно сделать с объектом я сделаю с помощью его собственных методов. Чаще всего в конвеерном стиле цепочки вызовов.
А отлаживать ты это дело пробовал? Лично для меня что b.A().A().A(), что B.A(B.A(b)) — выглядят одинаково криво, ровно потому, что поставить точку останова в нужном месте, большая проблема — это все к вопросу об удобстве.
Z>Я категорически не согласен с тем, что "нет разницы между вызовом экземплярных методов и методов статик хелперов".
см. выше, никто не призывает оставлять все статик хелперами.
Z>Я не согласен с тем, что удобством использования класса можно пренебречь при его проектировании.
"Удобство" штука весьма относительная. С функциональными языками по первости возиться знаешь как неудобно?
"Ты их в дверь — они в окно...
нет ребята, с этим делом мы покончили давно" (с) В.Высоцкий
IB>Здравствуйте, stump, Вы писали:
S>>на 1 процентный пункт. IB>Так там и кода на наперсток.
S>>Без хелпера связность 6, с хэлпером связность 7. IB>Ты все напутал, не "связность", а "связь между классами". Тебе еще раз определение связности привести?
Написано "Class Coupling: 6"
Написано: "In computer science, coupling or dependency is the degree to which each program module relies on each one of the other modules. Coupling is usually contrasted with cohesion. Low coupling often correlates with high cohesion, and vice versa." (Wikipedia)
В метрике связности число связей в числителе, число модулей в знаменателе. О чем тут еще можно спорить?
S>>Что и требовалось доказать. IB>В итоге ты доказал ровно обратное. Главная метрика — это как раз индекс поддерживаемости. Большая связность, в конечном итоге, плоха именно плохой поддерживаемостью, и именно это тебе студия и насчитала.
Это ты ее объявил главной. Какие метрики важнее — это очень специфично и зависит от конкретного проекта и случая. Но не в этом дело. Метрика "Maintainability Index" изменилась на 1 при значении 92, а метрика "Class Coupling" изменилась на 1 при значении 6. То есть удельное изменение первой метрики составило 1.08%, а второй метрики 16.66%. Очевидно что изменение дизайна оказало наибольшее влияние на метрику "Class Coupling", при том, что остальные метрики кода остались практически неизменными. Следовательно, это изменение дизайна (вынос методов в хелпер класс) не изменяет функциональности и целенаправленно воздействует только на одну метрику кода, которая называется "Class Coupling" увеличивая ее значение в данном случае на 16.66%. Название метрики "Class Coupling" переводится как "связность классов".
Я просто поражен тем, что мне приходится вот так вот разжевывать эти очевидные вещи.
Это просто анализ метрик кода, я даже не делаю выводов хорошо это или плохо. Просто данный анализ опровергает многие из твоих утверждений, и в отличии от них он основан на инструментальных измерениях конкретного примера кода.
Здравствуйте, IB, Вы писали:
IB>Это просто промежуточный рефакторинг, помогающий перейти от захардкоженного в класс функционала к DI.
Моя очередь сказать: Уфф...
Если в данном рефакторинге есть необходимость — нормальный прием.
IB>А отлаживать ты это дело пробовал? Лично для меня что b.A().A().A(), что B.A(B.A(b)) — выглядят одинаково криво, ровно потому, что поставить точку останова в нужном месте, большая проблема — это все к вопросу об удобстве.
В студии это отлаживается дюже просто — через выделение нужного стека вызовов и quickwatch.
При условии, что нет побочных эффектов повторного вызова, а к этому всегда следует стремиться.
Если они есть придется слегка править код:
var result = b.A().A();
result = result.A();
Z>>Я категорически не согласен с тем, что "нет разницы между вызовом экземплярных методов и методов статик хелперов". IB>см. выше, никто не призывает оставлять все статик хелперами.
Ключевое слово здесь хелпер, а не статик.
Z>>Я не согласен с тем, что удобством использования класса можно пренебречь при его проектировании. IB>"Удобство" штука весьма относительная. С функциональными языками по первости возиться знаешь как неудобно?
Не знаю
Первое соприкосновение с лиспом в бытность студентом особых проблем не вызвало (хотя могу что-то не вспонмнить сейчас). Сразу стал писать как на императивном языке, потом понемногу приходило понимание какие плюсы дает функциональный стиль.
Эти плюсы остаются плюсами при применении в императивных приложениях.
Цепочки вызвов легко читаются программистами не программировавшими на ФЯ, у них есть несомненные достоинства,
1. порядок вызвов идет слева направо/сверху вних, в отличии от из центра вложенности к границам.
2. дополнительные аргументы переданные в методы видны невооруженным взглядом
Я вполне осознаю пользу рефакторинга в DI сервисы, но также вижу вред в ухудшении читабельности кода и увеличении количества сущностей которыми должен оперировать не резиновый мозг программиста.
Здравствуйте, IB, Вы писали:
MC>>Понял, реальных примеров привести не можете. IB>Я привел вполне реальный пример, много примеров. Я не виноват, что они тебе не нравятся. =)
Где ты там увидел пример про проблемы с классом String (как ты говоришь)? Просто 2 предложения теории, к тому же к классу String не имеющей никакого отношения. Я задал несколько раз конкретный вопрос, попросил привести КОНКРЕТНЫЙ пример про проблемы с классом STRING, раз ты говоришь что он неправильно спроектирован. Ты либо не читаешь вопрос, либо не понимаешь, либо не можешь привести пример, либо у тебя такая манера вести дискуссию, когда тебе задают один конкретный вопрос, а ты отвечаешь совсем другое, причем не раз.
MC>>- Ну вот надо все эти методы надо было вынести в отдельные классы, потому что в противном случае это косяк. MC>>- Почему косяк? MC>>- Ну вот связность, и все такое, и Мейерс заявил что "они ошибаются" MC>>- На практике в чем косяк? MC>>- Ну я же писал.. что косяк.. MC>>- Так в чем косяк на практие? MC>>- Ну связность.. и Мейерс говорил.. IB>Это ты сейчас с кем говорил?
К сожалению, это ты так ведешь дискуссию.
Здравствуйте, Аноним, Вы писали:
А>Есть класс, который реализует некую ф-ть А>class Object А>У него есть методы, типа А>GetName — имя А>GetSize — возвращает свой размер без учета детей А>GetChilds — возвращает список своих детей
А>Появилась необходимость написать ряд методов, типа расчета размера рекурсивно с учетом всех детей, генерации уникального имени среди детей и т.д А>Все эти методы могут быть реализованы за счет публичного интерфейса Object, поэтому включать их в класс Object не хочется. Пока свалил их как внешние ф-ции в отдельный фаил ObjectHelper в виде CalcFullObjectSize, GetObjectUniqChildName, но выглядит это не очень красиво... А>Кто как поступает с такими методами?
Кто-нибудь может доходчиво объяснить, зачем класть эти функции в еще один класс? Классы же нельзя расширять. Даже в .NET с ее extension methods, если я правильно понимаю, нельзя запихивать в объект статические члены.
Так вот, что мешает просто сделать свободные функции? Или этот класс живет в королевстве существительных? А то я так и представляю, что кто-то создал Object и ObjectHelper, а потом кому-то понадобилось CalcFullObjectSizeInPetabytes, он создает ObjectHelperHelper, который ссылается на ObjectHelper и его функции, и т. д.
Тем более, что свободные функции всё равно вылезут. Например, кому-то захочется знать количество детей, или имя в такой-то кодировке, он и напишет функции countChildren(Object o) { return o.GetChildren().size(); }, getNameUtf8(Object o) { return convert(o.GetName(), "UTF-8"); }.
Здравствуйте, Roman Odaisky, Вы писали:
RO>Кто-нибудь может доходчиво объяснить, зачем класть эти функции в еще один класс? Классы же нельзя расширять.
А зачем расширять статические классы?
RO> Даже в .NET с ее extension methods, если я правильно понимаю, нельзя запихивать в объект статические члены.
Что значит запихивать?
RO>Так вот, что мешает просто сделать свободные функции?
Отсутствие таковых в шарпе и джаве, к примеру.
... << RSDN@Home 1.2.0 alpha 4 rev. 1095 on Windows Vista 6.0.6001.65536>>
Здравствуйте, stump, Вы писали:
S>Написано "Class Coupling: 6"
Class Coupling — связь между классами.
S>Написано: "In computer science, coupling
Просто Coupling — связность.
S> О чем тут еще можно спорить?
Вот и я не понимаю, о чем: Написано же английским по белому " Low coupling refers to a relationship in which one module interacts with another module through a stable interface and does not need to be concerned with the other module's internal implementation"
Так вот interacts with another module through a stable interface — это и есть тот самый class coupling, который считает студия и в его большем количестве ничего плохого нет. А concerned with the other module's internal implementation — выражается в Maintainability index-е.
Хватит уже отговорки придумывать.
S>Это ты ее объявил главной.
У нас разговор о простоте поддержки кода. Class Coupling на нее мало влияет, а вот Maintainability index имеет самое прямое и непосредственное отношение, он по сути это и меряет — простоту поддержки кода.
S> Метрика "Maintainability Index" изменилась на 1 при значении 92, а метрика "Class Coupling" изменилась на 1 при значении 6.
Какая разница насколько изменилась метрика Class Coupling, если она не имеет никакого отношения к делу?
Давай опять по новой. Если следовать твоей логике, то DI — увеличивает связность, так как при использовании DI увеличивается Class Coupling по метрикам студии.
S> Очевидно что изменение дизайна оказало наибольшее влияние на метрику "Class Coupling",
Проблема только в том, что эта метрика имеет весьма посредственное отношение к обсуждаемому вопросу.
S>Название метрики "Class Coupling" переводится как "связность классов".
Class Coupling меряет связи классов через публичный контракт, которые считаются "хорошими" с точки зрения связности.
S>Я просто поражен тем, что мне приходится вот так вот разжевывать эти очевидные вещи.
А уж я-то как поражен! Просто не верится, что ты к таким слабым отмазкам прибегаешь...
S> Просто данный анализ опровергает многие из твоих утверждений,
Он не опровергает, а как раз подтверждает. Очень хорошо подтверждает, надеюсь, объяснил почему?
Давай еще раз, если не понятно. По неизвестной мне причине, ты, под связностью, понимаешь число связей между классами, тогда как вся прогрессивная общественность (см википедию) понимает под этим число неявных связей. При этом считается, что перевод неявных связей в явные связность уменьшает — надеюсь не надо объяснять почему? (Для примера см DI, который как раз этим и занимается)
Теперь давай разберем твой пример: Понятно, что связь между методом и классом есть всегда, явная она или не явная. Если метод внутри класса, то связь неявная, что выражается в меньшем числе метрики Class Coupling и меньшем Maintainability index-е, понятно, что поддерживать неявную связь сложнее чем явную. Как только мы вынесли метод наружу, увеличилось число явных связей (увеличилась метрика Class Coupling) и, как следствие, увеличилась метрика Maintainability index, говорящая о том, что такой код проще поддерживать.
ЧТД.
S>он основан на инструментальных измерениях конкретного примера кода.
И мне он этим тоже нравится..