Здравствуйте, Ziaw, Вы писали:
Z> Только не верю я в вынос методов как в эффективную меру борьбы с ошибками реализации.
Я тоже не верю.. Я на практике проверял, более чем эффективна.
Z>Тестирования, ревью кода, скил программистов решают эту проблему гораздо эффективнее.
А уж все в месте.. )
Z>Ужасов не будет если специалист узконаправлен и наизусть знает данную библиотеку.
Не надо знать наизусть. Достаточно знать что сущность имеет хелпер. Если же вся библиотека спроектирована в таком стиле, то очевидно, что сущность имеет хелпер.
(Под хелпером следует понимать хелпер, сервис, любой внешний функционал по ее обслуживанию) Внутрення логика хорошо прописанной библиотеки постигается в течении нескольких дней, дальше никаких проблем.
Z>Насколько я понял мысль — сервисов планируется не один.
Какая разница, если они четко сгруппированы по функциональному признаку и в хелпе они в любом случае проассоциированы с объектом, с которым работают?
Здравствуйте, Aikin, Вы писали:
A>Так и знал, что будут додумывания, появятся вопросы по отсутствующим классам...
Да нет же, мне вполне понятно общее направление твоей мысли. Я просто хочу уточнить критерии, которыми ты наверняка руководствовался, но не упомянул о них.
A>События тут явно лишние. A>Тут лишние. Можно привести примеры задачи когда child-объектам нужно уведомить о чем нибудь своего парента. Но в этом случае лучше использовать цепочку обязанностей, так как инициаторы события (дети) знают о его получателях (родители).
Пока не знают, но сделаем чтоб знали, согласен. Вот тут возникает вопрос: тем самым мы еще больше усиливаем связность между Order и OrderLine, что вроде бы плохо в общем случае. Но в этом конкретном случае на усиление связи можно мело наплевать, нам понятно что мы никогда не будем использовать OrderLine отдельно от Order.
Это к вопросу о необходимости проектирования по "четко определенным" критериям.
A>А АОП совсем не причем. Где ты тут разглядел аспект?
При изменении любого свойства надо кого-то оповещать. Как-то так...
A>Конечно же нет. Каждая ставка утверждается государством. Изменения происходят не чаще раза год. Ну не чаще раза в месяц. Самое главное, что в момент формирования заказа и в момент его оплаты об изменении этой ставки можно забыть!
Ну ставка налога да. Но на ее месте может быть тарифная ставка, или вообще какая нибудь скидка (суперакция! только один день 31 июня! скидка 50%! спешите персчитать все ваши отложенные ордера! ) S>>В общем тут пересчет суммы ордера, вынесенный в отдельный сервисный класс, представляется более предпочтительным. A>В явно зверской версии ТЗ -- да. Но в реальной ситуации -- нет.
Бизнес требования порой превосходят любую нашу фантазию...
Здравствуйте, IB, Вы писали:
IB>Я этот аргумент выдвигал раз пять. Каждый раз его молча игнорировали, отсюда делаем вывод, что возразить нечего.
Про лучше/хуже говорят остальные пункты.
Z>>Может стоит ввести в язык новый модификатор метода который имеет доступ только к публичным членам? IB>Возможно, но я бы предпочел методы расширения в экземплярных классах...
Я бы тоже не отказался. Насчет предпочел не понял, вроде не было ограничения либо/либо.
Z>>Что мешает мокать при вызове собственных методов? IB>Методы придется тестировать вместе с классом, а так можно по отдельности.
Вместе с моком? Какая разница как передавать мок? Как this или параметром?
Разница только в доступе метода к закрытым членам, но это обсуждается выше.
Здравствуйте, IB, Вы писали:
A>>А тебе никто не приведёт пример, когда правило не получается применить. IB>Конечно, его же нет..
Видимо ты совсем не понимаешь, что возможности применения правила и оправданность применения правила суть разные вещи.
A>>Правильный и красивый дизайн библиотеки подразумевает в первую очередь удобство использования, а не лёгкость поддержки. IB>Весьма спорный тезис. Если удобству использования приносится в жертву надежность, то нафиг-нафиг такую библиотеку.
Это уже ты придумал, что что-то приноситься в жертву. А тезис не спортный, библиотека одна, приложений много. Об этом уже говорили, но ты, видимо, пропустил.
A>> С чего это она начнёт считать неправильно? IB>С того что код получился менее надежный
Фантазии или догматический страх? Видимо тебе приходиться придумывать аргументы, очень жаль.
IB>Придется переучиваться..
Ради святого правила? Не, не айс.
IB>На такой, что она более надежна.
Это не правда, это домыслы. Видимо тебе приходиться придумывать аргументы, очень жаль.
A>>Ты действительно думаешь что твой или ещё какой-то рейтинг чем-то принципиально осмысленнее чем LOC/day и его область применения не узка? IB>Ты что этим сказать-то хотел?
Я хотел сказать что твой или ещё какой-то рейтинг принципиально ничуть не осмысленнее чем LOC/day и его область применения узка.
IB>Да, и для этого хелперы тоже можно использовать..
Много чего можно делать через задницу.
A>>Это решение было всегда, и в C#, и в Си++ и в Object Pascal. IB>Потому что наследование катастрофически увеличивает связность. При нормальном дизайне случаи использования наседования можно по пальцам пересчитать. Агрегация в большинстве случаев намного предпочтительнее.
Глупости, связность никак не увеличилась, связь между хелпером и классом была и так и она не стала сильнее. В данном конктерном случае есть организационное преимущество. Мы делаем расширитель конкретного класса. Хелперы не связаны с расширяемыми классами синтаксически связями и, как результат, хелперы часто превращаются в свалку методов не влезающих в другие классы. Свалку методов разных классов, хорошо ещё если классов одного семейства. Наследование позволяет строго ограничить что именно данный расширитель расширяет. Это и поддерживаемость кода улучшает и ошибки уменьшает
S>Пока не знают, но сделаем чтоб знали, согласен. Вот тут возникает вопрос: тем самым мы еще больше усиливаем связность между Order и OrderLine, что вроде бы плохо в общем случае. Но в этом конкретном случае на усиление связи можно мело наплевать, нам понятно что мы никогда не будем использовать OrderLine отдельно от Order.
+1 Но я все же за иммунабл.
A>>А АОП совсем не причем. Где ты тут разглядел аспект? S>При изменении любого свойства надо кого-то оповещать. Как-то так...
Аспектно-ориентированное программирование (АОП) — парадигма программирования, основанная на идее разделения функциональности, особенно сквозной функциональности, для улучшения разбиения программы на модули.
ИМХО, аспект -- что-то общее для приложения, а не для конкретного класса или связи классов, что-то что можно добавить к уже написанному, отлаженному и хорошо работающему классу.
Аспектом может быть логирование (наиболее частоприводимый пример), секьюрити (очень удобно делать секьюрити на аспектах, так как оно не должно входить в обязанности защищаемых объектов).
S>Ну ставка налога да. Но на ее месте может быть тарифная ставка, или вообще какая нибудь скидка (суперакция! только один день 31 июня! скидка 50%! спешите персчитать все ваши отложенные ордера! )
Да, косячек какой-то. Вводить метод RecalculateTotal() не хочется. Надо обдумать этот момент. Как придумаю (если придумаю) отпишусь.
S>>>В общем тут пересчет суммы ордера, вынесенный в отдельный сервисный класс, представляется более предпочтительным. A>>В явно зверской версии ТЗ -- да. Но в реальной ситуации -- нет. S>Бизнес требования порой превосходят любую нашу фантазию...
Здравствуйте, IB, Вы писали:
IB>Здравствуйте, Ziaw, Вы писали:
Z>> Только не верю я в вынос методов как в эффективную меру борьбы с ошибками реализации. IB>Я тоже не верю.. Я на практике проверял, более чем эффективна.
Т.е. был поставлен эксперимент? Можно узнать подробности?
Точные данные по трудозатратам на редизайн.
Точные данные сэкономленого времени на порог вхождения.
Без таких данных я предпочитаю говорить верю, хотя мне и кажется, что знаю.
Я на практике тоже покушал хелперов и порефакторил.
IB>Не надо знать наизусть. Достаточно знать что сущность имеет хелпер. Если же вся библиотека спроектирована в таком стиле, то очевидно, что сущность имеет хелпер. IB>(Под хелпером следует понимать хелпер, сервис, любой внешний функционал по ее обслуживанию) Внутрення логика хорошо прописанной библиотеки постигается в течении нескольких дней, дальше никаких проблем. IB>Какая разница, если они четко сгруппированы по функциональному признаку и в хелпе они в любом случае проассоциированы с объектом, с которым работают?
Давай так, каждый выберет пример библиотеки реализованой по удобной ему идеологии и попытаемся их сравнить.
Я готов поверить, что теоретически можно спроектировать так сказочно, просто все эти библиотеки гдето за NDA наверное.
Здравствуйте, adontz, Вы писали:
A>Здравствуйте, samius, Вы писали:
S>>Это может привести потребителя к лишней неоднозначности.
A>Как ми образов если он не видит базовый класс?
Видит производный но не видит базовый? так не бывает. У базового видимость не меньше чем у производного.
Здравствуйте, adontz, Вы писали:
A>А вот и то самое "ниже", которое я дважды обещал. Вот пример, наглядный. Есть методы A и B у класса C. A требует доступа к приватной перменной _x, B не требует.
Вот с этим я сильно не согласен. С увеличением количества приватных переменных _x получаем некислый комбинаторный взрыв наследования.
Здравствуйте, minorlogic, Вы писали:
M>http://www.softcraft.ru/coding/sm/sm01.shtml
M>Если ссылка еще не пробегала.
Так вот откуда ноги растут у "железного правила"
Дело в том, что во-первых правило Мейерса сформулировано не столь категорично как "железное правило Бодягина". Мейерс вспомнил про виртуализацию и про особые случаи.
Во-вторых, Мейерс сформулировал свое правило для C++, с его особенностями реализации OOP, и основные бенефиты, которые он там описывает не работают в C# (хотя само правило, за исключением специфической C++ятины, работает конечно).
В общем, как тут уже говорили "использование правил не отменяет использование головы".
Здравствуйте, Ziaw, Вы писали:
Z>Вот с этим я сильно не согласен. С увеличением количества приватных переменных _x получаем некислый комбинаторный взрыв наследования.
Почему у тебя количество наследников отличается от количества хелперов? В чём усложнение?
Здравствуйте, adontz, Вы писали:
A>Здравствуйте, samius, Вы писали:
S>>Видит производный но не видит базовый? так не бывает. У базового видимость не меньше чем у производного.
A>Не может содавать базовый, базовый не фигурирует нигде. И в чём тогда разница?
Я так понимаю, что в случае C : CBase класс C принимает роль хелпера. Значит для метода B1() может понадобиться класс C1 : CBase, и т.д.
Но тогда не удастся вызвать методы B() и B1() для одного экземпляра объекта. А в случае хелперов без наследования это возможно в виде BHelper.B(c) и B1Helper.B1(c). Либо методы B и B1 в классе C, либо в хелперах.
Здравствуйте, samius, Вы писали:
S>Но тогда не удастся вызвать методы B() и B1() для одного экземпляра объекта. А в случае хелперов без наследования это возможно в виде BHelper.B(c) и B1Helper.B1(c). Либо методы B и B1 в классе C, либо в хелперах.
Да, наследник один. Это минус, вне всякого сомнения, но я на практике не сталкивался с логической необходимостью делать больше одного хелпера. Я предпочитаю partial классы. Формально класс один, но и разбиение методов на группы есть. Все счастливы
Здравствуйте, adontz, Вы писали:
A>Почему у тебя количество наследников отличается от количества хелперов? В чём усложнение?
Прошу прощения
Я поторопился и развил мысль дальше =) Когда кто-то добавит приватное поле в наследника.
Если этого не делать никакого отличия нет. Кроме того, что хелперов можно сделать несколько без ущерба для функционала, а наследеников нельзя.
Здравствуйте, Ziaw, Вы писали:
IB>>Я тоже не верю.. Я на практике проверял, более чем эффективна. Z>Т.е. был поставлен эксперимент? Можно узнать подробности? Z>Точные данные по трудозатратам на редизайн. Z>Точные данные сэкономленого времени на порог вхождения.
Да ничего он тебе не ответит. Одни слова. Как задаешь конкретный вопрос — получаешь ответ не по теме.
Z>Давай так, каждый выберет пример библиотеки реализованой по удобной ему идеологии и попытаемся их сравнить.
Ему уже был задан вопрос привести пример когда на практике есть (по его словам) неудобства с использованием класса String. Ответа не было.
Для C++ этот алгоритм отлично работает. А C# все осложняется тем, что свободных функций нет (поправьте меня, если я ошибаюсь). Использование классов-помощников не всегда удобно. Вот отсюда и конфликт.