Re[44]: Куда девать ф-ции внешние для класса
От: Ziaw Россия  
Дата: 28.07.08 21:28
Оценка:
Здравствуйте, AndrewVK, Вы писали:

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


Z>>public static AddAll<T>(this ISet<T> set, IEnumerable<T> items)

Z>>{
Z>> if (set is ISynchronizedSet)

AVK>Да уж. А сделать:


AVK>
AVK>public static AddAll<T>(this ISynchronizedSet<T> set, IEnumerable<T> items)
AVK>

AVK>Религия мешает?
Ну вообще-то я не планировал открывать наружу ISynchronizedSet, а использовал его как internal проводник private поля.

Хотя смысл открыть наружу его есть, только тогда придется вылавливать ошибки там, где люди написали:
ISet s = new SynchronizedSet();
s.AddAll(collection);


В принципе для таких случаев можно придумать экзамен, пусть 100 раз на доске напишут.

Если мне нужна синхронизация при вызове AddAll я всегда буду строго указывать тип ISynchronizedSet.



Z>>Ужас он не от того, что мне пришлось это сделать, а от того, что я понимаю, что еще пара вариантов реализации AddAll и мне придется признаться, что мой дизайн унылое г.


AVK>Неа, унылое гавно, это когда в уже существующих методах вдруг появляется блокировка. Ну а главное — тема сис... вынесения методов не раскрыта. Где здесь преимущество варианта, когда твои AddAll находятся в ISet?

Меня тут просто замучали тыкать в факт того, что появиться может что угодно и где угодно!
При этом упирая на то, что вынос методов служит как раз облегчения расширения в таких ситуациях.
Как только этот факт перестал работать вашу пользу — его сразу списали в канализацию.
... << RSDN@Home 1.2.0 alpha 4 rev. 1096>>
Re[44]: Куда девать ф-ции внешние для класса
От: Ziaw Россия  
Дата: 28.07.08 21:34
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Ну а главное — тема сис... вынесения методов не раскрыта. Где здесь преимущество варианта, когда твои AddAll находятся в ISet?


Тут как раз просто, я его могу переопределить в классе SynchronizedSet.
... << RSDN@Home 1.2.0 alpha 4 rev. 1096>>
Re[45]: Куда девать ф-ции внешние для класса
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 28.07.08 21:35
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Ну вообще-то я не планировал открывать наружу ISynchronizedSet


Ну начинается.

Z>Меня тут просто замучали тыкать в факт того, что появиться может что угодно и где угодно!


Увы, но это действительно непреложый факт.

Z>При этом упирая на то, что вынос методов служит как раз облегчения расширения в таких ситуациях.


Ага.

Z>Как только этот факт перестал работать вашу пользу — его сразу списали в канализацию.


Кого списали в канализацию? Я лично никого в канализацию не списывал.
AVK Blog
Re[13]: Куда девать ф-ции внешние для класса
От: Юрий Жмеренецкий ICQ 380412032
Дата: 28.07.08 21:37
Оценка:
Здравствуйте, adontz, Вы писали:

A>Здравствуйте, Юрий Жмеренецкий, Вы писали:


A>>>Давай поставим вопрос ребром, зачем ты вообще решил увеличивать инкапуляцию? Ради упрощения поддержки?

ЮЖ>>Т.е. результативнее снизить количество необходимых изменений, а не улучшать их "удобство". Как минимум, уменьшается объем потенциально возможных ошибок, набор тестов, да и просто количество необходимого времени.

A>Верно, но не про нас. То где находится метод: в классе или хелпере, никак не влияет ни на возможность его тестировать, ни на возможность его поменять или добавить новый метод. Прсото взяли и для себя упорядочили. Подчёркиваю, для себя. Другим эта упорядоченность на фиг не упала.

Еще как упала. Раз уж была упомянута STL: хороший пример — разделение алгоритмов и контейнеров: все что необходимо, так это предоставить пару итераторов — все остальное начнет работать автоматически. То же и для алгоритмов поверх любых контейнеров. А что будет если слить все в кучу ?

ЮЖ>>один класс должен иметь только одну причину для изменения.

A>Утверждение, которое можно трактовать как угодно.
Отнюдь, трактовка ровно одна: один класс — одна причина для изменений.
Вот AndrewVK рядом(не знаю как ссылки на конкретные сообщения из плоского веб-интерфейса вставлять) про реструктуризатор писал:

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

Здесь множество причин для изменений. Я про это.


ЮЖ>>А вот снижение количества изменений, снижение количества потенциально возможных багов порожденных этими изменениями, снижение объемов тестирования, уменьшение времени, затраченного на эти изменения, увеличиние скорости реализации новых фич и т.п., — все это тоже в конечном итоге средства снижения стоимости и увеличения конкурентноспособности.


A>ОК, как вынос метода в хелпеер на это влияет? А? Не изменение архитектуры, а просто взяли и сделали второй класс и вытащили туда всё чему достаточно публичного контракта.

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

ЮЖ>>Повторному использованию, имхо, очень часто мешают лишние ответственности.

A>Опять не в тему. Библиотека не стала делать больше или меньше, просто методы перераскидали по классам.
Тогда зачем вообще раскидывать? — один класс на библиотеку, да и не мучиться...

ЮЖ>>А такой код(библиотечный) тем более должен стремится к применению SRP по максимуму. Если я хочу от библиотеки 'A', то она и должна мне предоставить 'A', а не ['A' + 'B' + на всякий случай 'C' для удобства] в одном флаконе. Это просто снижает повторное использование(вместе с окупаемостью).


A>Опять не в тему. Библиотека не стала делать больше или меньше, просто методы перераскидали по классам.

Из нескольких классов, которые можно использовать независимо, проще собирать то что необходимо.

ЮЖ>>Можно пойти еще дальше и оставить только два итератора, плюс сделать строку иммутабельной и добавить string builder.

A>И получить STL где у сттроки нет нормального find
А нормальный это какой ? с регэкспами и поиском через гугл?

A>И каждый пишет свой.

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

A>Не надо SRP доводить до маразма стимулирую написание велосипедов.

Не надо доводить до маразма кажущееся "удобство" в виде автокомплита. Иначе чем объяснить изначальное существование в классе методов которых там не должно быть?

ЮЖ>>Т.е. автокомплит, если я правильно понял всю ветку — это и есть удобство?

A>Конечно, автокомплит увеличивает производительность. Кто бы спорил.
Увеличивает производительность чего ? навигации по толстым классам ? Сначала сделали себе проблему, а потом ее же и решаем =)
Ничего против автокомплита не имею, но неужели это действительно может рассматриваться как критерий выбора библиотеки ?
Re[45]: Куда девать ф-ции внешние для класса
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 28.07.08 21:44
Оценка: +1
Здравствуйте, Ziaw, Вы писали:

Z>Тут как раз просто, я его могу переопределить в классе SynchronizedSet.


И чем это лучше AddAllSync? А что, если для одной и той же коллекции нужен и с блокировкой доступ и без онной (как минимум в конструкторе с сигнатурой (IEnumerable<T>) блокировка не нужна)? Вводить специальное свойство еще — IsLockActive? Как думаешь, почему в ICollection есть свойства IsSynchronized и SyncRoot, а в ICollection<T> уже ничего подобного нет? Почему близкий по семантике твоему примеру метод Union находится в хелпере, а не в интерфейсе IEnumerable<T>? Это все ошибки дизайна? Какие из методов класса Enumerable по твоему должны находиться в интефейсе IEnumerable<T> и почему? А какие не должны и почему?
AVK Blog
Re[46]: Куда девать ф-ции внешние для класса
От: Ziaw Россия  
Дата: 28.07.08 21:46
Оценка:
Здравствуйте, AndrewVK, Вы писали:

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


Z>>Ну вообще-то я не планировал открывать наружу ISynchronizedSet

AVK>Ну начинается.
Что начинается? Не открою плохо, открою еще хуже.

Z>>Меня тут просто замучали тыкать в факт того, что появиться может что угодно и где угодно!

AVK>Увы, но это действительно непреложый факт.
Z>>При этом упирая на то, что вынос методов служит как раз облегчения расширения в таких ситуациях.
AVK>Ага.
Так вот вполне реалистичная ситуация когда появившееся требование ложится на дизайн с вынесенным методом гораздо хуже чем на экземплярный.

Z>>Как только этот факт перестал работать вашу пользу — его сразу списали в канализацию.

AVK>Кого списали в канализацию? Я лично никого в канализацию не списывал.
А как же это?
AVK>Неа, унылое гавно, это когда в уже существующих методах вдруг появляется блокировка
... << RSDN@Home 1.2.0 alpha 4 rev. 1096>>
Re[46]: Куда девать ф-ции внешние для класса
От: Ziaw Россия  
Дата: 28.07.08 22:00
Оценка:
Здравствуйте, AndrewVK, Вы писали:

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


Z>>Тут как раз просто, я его могу переопределить в классе SynchronizedSet.

AVK>И чем это лучше AddAllSync?
Лучше тем, что передав экземпляр SynchronizedSet активно исползующийся в другом треде в любой метод с принимающий ISet я не буду гадать, будет там вызван AddAll или нет.

AVK>А что, если для одной и той же коллекции нужен и с блокировкой доступ и без онной (как минимум в конструкторе с сигнатурой (IEnumerable<T>) блокировка не нужна)? Вводить специальное свойство еще — IsLockActive?

В чьем конструкторе?

AVK>Как думаешь, почему в ICollection есть свойства IsSynchronized и SyncRoot, а в ICollection<T> уже ничего подобного нет?

Почему? Мне правда интересно.

AVK>Почему близкий по семантике твоему примеру метод Union находится в хелпере, а не в интерфейсе IEnumerable<T>?

Как минимум по причине обратной совместимости.

AVK>Это все ошибки дизайна? Какие из методов класса Enumerable по твоему должны находиться в интефейсе IEnumerable<T> и почему? А какие не должны и почему?


Я не выдумывал правил по выносу, я только показал, что правило выдуманное IB для улучшения расширяемости может сработать с точностью до наоборот.
... << RSDN@Home 1.2.0 alpha 4 rev. 1096>>
Re[43]: Куда девать ф-ции внешние для класса
От: Юрий Жмеренецкий ICQ 380412032
Дата: 28.07.08 22:02
Оценка: +3
Здравствуйте, Ziaw, Вы писали:

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


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


Z>>>Какой мне предпочесть опираясь на OCP или другие соображения?


AVK>>
AVK>>public static AddAll<T>(this ISet<T> set, IEnumerable<T> items)
AVK>>


Z>Отлично, я быстренько все это пишу. Отдаю библиотеку все используют — все в восторге.

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

Кстати, раз вопрос коснусля блокировок: внутренняя блокировка в контейнере — вещь практически бесполезная. Блокировка контейнеров должна быть внешней. Вот скажем мне нужно за одну блокировку вызвать три раза AddAll для разных источников...
Re[47]: Куда девать ф-ции внешние для класса
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 28.07.08 22:03
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>>>Ну вообще-то я не планировал открывать наружу ISynchronizedSet

AVK>>Ну начинается.
Z>Что начинается?

Начинается изменение задачи на ходу. Т.е. требовать в примере с Substring абсолютной конкретики можно, а тут вдруг задача с каждым сообщением меняется произвольным образом. Если хочешь конкретики — то твое решение никуда не годится, прозрачное и закрытое введение блокировки до добра не доводит. Завтра тебе понадобится несколько последовательных добавлений и удалений — будем вводить в базовый интерфейс метод AddAndRemoveAll? А знаешь в чем самое веселое — вариант с хелперами легко и непринужденно превращается в вариант с методами класса, причем, благодаря extension методам, еще и абсолютно прозрачно для прикладного кода, использующего ISet, на уровне исходников (т.е. код надо просто перекомпилировать). А вот если ты вкрячил AddAll в ISet, а в результате никаких синхронизаций не понадобилось, выкинуть его оттуда будет ой как непросто. И придется несчастным реализаторам копипейстить один и тот же код твоих AddAll. Так где здесь унылое гавно в дизайне?

Z>Так вот вполне реалистичная ситуация когда появившееся требование ложится на дизайн с вынесенным методом гораздо хуже чем на экземплярный.


Пока что я вижу обратное.

AVK>>Кого списали в канализацию? Я лично никого в канализацию не списывал.

Z>А как же это?
AVK>>Неа, унылое гавно, это когда в уже существующих методах вдруг появляется блокировка

То есть факт, который работал в нашу пользу — это когда в уже существующих методах вдруг появляется блокировка?
Слушай, мне совершенно не интересно доказывать, что я прав. Если тебе так будет приятно — я признаю что прав ты и больше не буду с тобой спорить.
... << RSDN@Home 1.2.0 alpha 4 rev. 1095 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[47]: Куда девать ф-ции внешние для класса
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 28.07.08 22:11
Оценка: +1
Здравствуйте, Ziaw, Вы писали:

Z>>>Тут как раз просто, я его могу переопределить в классе SynchronizedSet.

AVK>>И чем это лучше AddAllSync?
Z>Лучше тем, что передав экземпляр SynchronizedSet активно исползующийся в другом треде в любой метод с принимающий ISet я не буду гадать, будет там вызван AddAll или нет.

Понимаешь, блокировка такая штука, что ее не стоит прятать внутри. Иначе такие суперрешения будут — мама не горюй, перерасход на блокировках и дедлоки. Только внешний код знает, как правильно расставлять локи, не надо это внутрь коллекций запихивать. Максимум что тут можно сделать — ввести специальную синхронизированную коллекцию с методами, находящимися в публичном интерфейсе класса, но не в ISet, либо отдельный хелпер, увязанный, опять же, не с ISet, а с конкретным синхронизированным классом. Именно так устроен CDS (Coordination Data Structures), в отличие от кривого решения в первом фреймворке.

AVK>>А что, если для одной и той же коллекции нужен и с блокировкой доступ и без онной (как минимум в конструкторе с сигнатурой (IEnumerable<T>) блокировка не нужна)? Вводить специальное свойство еще — IsLockActive?

Z>В чьем конструкторе?

В конструкторе твоей синхронизированной коллекции.

AVK>>Как думаешь, почему в ICollection есть свойства IsSynchronized и SyncRoot, а в ICollection<T> уже ничего подобного нет?

Z>Почему? Мне правда интересно.

См. выше.

AVK>>Почему близкий по семантике твоему примеру метод Union находится в хелпере, а не в интерфейсе IEnumerable<T>?

Z>Как минимум по причине обратной совместимости.

Ага, так значит хелперы таки работают в плане обратной совместимости? Хорошо, тогда следующий вопрос — почему аналогичную ситуацию мы видим в классе Queryable? Ведь IQueryable до этого в фреймворке не было, следовательно никаких проблем с совместимосттью нет?

Z>Я не выдумывал правил по выносу, я только показал, что правило выдуманное IB для улучшения расширяемости может сработать с точностью до наоборот.


Пока что ты этого не показал.
... << RSDN@Home 1.2.0 alpha 4 rev. 1095 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[48]: Куда девать ф-ции внешние для класса
От: Ziaw Россия  
Дата: 28.07.08 22:22
Оценка:
Здравствуйте, AndrewVK, Вы писали:

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


Где задача поменялась?
Я написал чистую правду, что не планировал показ интерфейса наружу, об этом вполне конкретно говорит модификатор internal в исходном сообщении.

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

AVK> Если хочешь конкретики — то твое решение никуда не годится, прозрачное и закрытое введение блокировки до добра не доводит. Завтра тебе понадобится несколько последовательных добавлений и удалений — будем вводить в базовый интерфейс метод AddAndRemoveAll? А знаешь в чем самое веселое — вариант с хелперами легко и непринужденно превращается в вариант с методами класса, причем, благодаря extension методам, еще и абсолютно прозрачно для прикладного кода, использующего ISet, на уровне исходников (т.е. код надо просто перекомпилировать).

Точно также легко и непринужденно с совместимостью на уровне исходников метод при необходимости выносится в extensions. О чем мы тогда спорим?

AVK>А вот если ты вкрячил AddAll в ISet, а в результате никаких синхронизаций не понадобилось, выкинуть его оттуда будет ой как непросто. И придется несчастным реализаторам копипейстить один и тот же код твоих AddAll. Так где здесь унылое гавно в дизайне?

Унаследоваться от AbstractSet им религия помешает?

AVK>>>Кого списали в канализацию? Я лично никого в канализацию не списывал.

Z>>А как же это?
AVK>>>Неа, унылое гавно, это когда в уже существующих методах вдруг появляется блокировка
AVK>То есть факт, который работал в нашу пользу — это когда в уже существующих методах вдруг появляется блокировка?
Нет, более общий факт, когда начинает требоваться полиморфное поведение вынесенного наружу метода.

AVK>Слушай, мне совершенно не интересно доказывать, что я прав. Если тебе так будет приятно — я признаю что прав ты и больше не буду с тобой спорить.

Признай Я только за.
... << RSDN@Home 1.2.0 alpha 4 rev. 1096>>
Re[44]: Куда девать ф-ции внешние для класса
От: adontz Грузия http://adontz.wordpress.com/
Дата: 28.07.08 22:30
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Ну а главное — тема сис...


— А! Кто подонки?! Где подонки?!
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[49]: Куда девать ф-ции внешние для класса
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 28.07.08 22:31
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Где задача поменялась?


То был метод с единственной реализацией, то вдруг синхронизация откуда то вылезла.

Z>Я написал чистую правду, что не планировал показ интерфейса наружу, об этом вполне конкретно говорит модификатор internal в исходном сообщении.


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

Z>Точно также легко и непринужденно с совместимостью на уровне исходников метод при необходимости выносится в extensions.


Увы нет. Добавление элемента в контракт всегда проще, чем удаление его оттуда.

Z>Унаследоваться от AbstractSet им религия помешает?


То есть мы еще и абстрактный класс нарисуем? И тесно увяжем все реализации с твоим AbstractSet? А если пользюковые классы имеют свою иерархию наследования, куда твой AbstractSet вкрячить не получится? Например от MBR надо наследоваться?

AVK>>То есть факт, который работал в нашу пользу — это когда в уже существующих методах вдруг появляется блокировка?

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

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

Z>Признай Я только за.


Хорошо, ты прав. Теперь можно обходится без подобных приемчиков?
... << RSDN@Home 1.2.0 alpha 4 rev. 1095 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[48]: Куда девать ф-ции внешние для класса
От: Ziaw Россия  
Дата: 28.07.08 22:40
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Понимаешь, блокировка такая штука, что ее не стоит прятать внутри. Иначе такие суперрешения будут — мама не горюй, перерасход на блокировках и дедлоки. Только внешний код знает, как правильно расставлять локи, не надо это внутрь коллекций запихивать. Максимум что тут можно сделать — ввести специальную синхронизированную коллекцию с методами, находящимися в публичном интерфейсе класса, но не в ISet, либо отдельный хелпер, увязанный, опять же, не с ISet, а с конкретным синхронизированным классом. Именно так устроен CDS (Coordination Data Structures), в отличие от кривого решения в первом фреймворке.


Пример был просто придуман на скорую руку для демонстрации появления требования приводящего к полиморфному поведению вынесенного метода. Или такое требование реально только в высосаных из пальца ситуациях?

За советы по поводу синхронизации спасибо, познавательно.

AVK>>>А что, если для одной и той же коллекции нужен и с блокировкой доступ и без онной (как минимум в конструкторе с сигнатурой (IEnumerable<T>) блокировка не нужна)? Вводить специальное свойство еще — IsLockActive?

Z>>В чьем конструкторе?
AVK>В конструкторе твоей синхронизированной коллекции.
А зачем в конструкторе вызывать виртуальный метод?

AVK>Ага, так значит хелперы таки работают в плане обратной совместимости?

Я гдето утверждал обратное? Всегда считал их хорошим средством расширения.

AVK>Хорошо, тогда следующий вопрос — почему аналогичную ситуацию мы видим в классе Queryable? Ведь IQueryable до этого в фреймворке не было, следовательно никаких проблем с совместимосттью нет?

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

Z>>Я не выдумывал правил по выносу, я только показал, что правило выдуманное IB для улучшения расширяемости может сработать с точностью до наоборот.

AVK>Пока что ты этого не показал.
Буду дальше стараться. Для меня это очевидно.
... << RSDN@Home 1.2.0 alpha 4 rev. 1096>>
Re[14]: Куда девать ф-ции внешние для класса
От: adontz Грузия http://adontz.wordpress.com/
Дата: 28.07.08 22:41
Оценка:
Здравствуйте, Юрий Жмеренецкий, Вы писали:

ЮЖ>Еще как упала. Раз уж была упомянута STL: хороший пример — разделение алгоритмов и контейнеров: все что необходимо, так это предоставить пару итераторов — все остальное начнет работать автоматически. То же и для алгоритмов поверх любых контейнеров. А что будет если слить все в кучу ?


.Net Framework Class Library?

ЮЖ>Здесь множество причин для изменений. Я про это.


Ты как-то криво обозвал SRP. SRP как и любой другой принцип не самоцель и не надо под алгом больбы с классами занимающимися сразу несколькими задачами измельчать всё что можно и нельзя. Есть классы, которые не просто содержат сотню методов, это абсолютно нормально в предметной области их использования.

ЮЖ>Тогда зачем вообще раскидывать? — один класс на библиотеку, да и не мучиться...


Раскидывать надо не ради процесса раскидывания, а ради построения понятного, удобного интерфейса.

ЮЖ>Из нескольких классов, которые можно использовать независимо, проще собирать то что необходимо.


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

A>>И получить STL где у сттроки нет нормального find

ЮЖ>А нормальный это какой ? с регэкспами и поиском через гугл?

Досстаточно регэкспов.

ЮЖ>Может быть. В зависимости от задачи. Со строками проблема в том, что там слишком много потенциально настраиваемых моментов, и при попытке свалить все в кучу получится вышеупомянутый реструктуризатор.


Да вот System.String как-то всем хватает.

ЮЖ>Не надо доводить до маразма кажущееся "удобство" в виде автокомплита. Иначе чем объяснить изначальное существование в классе методов которых там не должно быть?


Соответствие логике предметной области.

ЮЖ>Ничего против автокомплита не имею, но неужели это действительно может рассматриваться как критерий выбора библиотеки ?


Близость объектной модели и реалий предметной области — критерий.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[50]: Куда девать ф-ции внешние для класса
От: Ziaw Россия  
Дата: 28.07.08 22:47
Оценка:
Здравствуйте, AndrewVK, Вы писали:

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


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

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

Z>>Точно также легко и непринужденно с совместимостью на уровне исходников метод при необходимости выносится в extensions.

AVK>Увы нет. Добавление элемента в контракт всегда проще, чем удаление его оттуда.
Чем?

AVK>Хорошо, ты прав. Теперь можно обходится без подобных приемчиков?

Постараюсь.
... << RSDN@Home 1.2.0 alpha 4 rev. 1096>>
Re[49]: Куда девать ф-ции внешние для класса
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 28.07.08 22:49
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Пример был просто придуман на скорую руку для демонстрации


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

Z> появления требования приводящего к полиморфному поведению вынесенного метода


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

Z>За советы по поводу синхронизации спасибо, познавательно.


Зато абсолютно не в тему. Что и ожидалось.

AVK>>В конструкторе твоей синхронизированной коллекции.

Z>А зачем в конструкторе вызывать виртуальный метод?

То есть у тебя будут две реализации AddAll внутри, одна виртуальная, другая нет? Да и почему виртуальный? Для реализации интерфейса виртуальность не обязательна, интерфейс свою виртуальность добавит.

AVK>>Ага, так значит хелперы таки работают в плане обратной совместимости?

Z>Я гдето утверждал обратное?

Что тогда ты пытаешься доказать?

AVK>>Хорошо, тогда следующий вопрос — почему аналогичную ситуацию мы видим в классе Queryable? Ведь IQueryable до этого в фреймворке не было, следовательно никаких проблем с совместимосттью нет?

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

IQueryable, как несложно догадаться из названия, это интерфейс и никакого наследования от абстрактного класса он не требует.
... << RSDN@Home 1.2.0 alpha 4 rev. 1095 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[51]: Куда девать ф-ции внешние для класса
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 28.07.08 22:59
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>>>Точно также легко и непринужденно с совместимостью на уровне исходников метод при необходимости выносится в extensions.

AVK>>Увы нет. Добавление элемента в контракт всегда проще, чем удаление его оттуда.
Z>Чем?

Тем, что про новый член никто не знает, и его добавление по сути совсем не меняет семантику использующего кода (если только не умудрились дать возможность с его помощью поломать инварианты). А вот удаление метода безусловно меняет семантику тех кусков, которые его использовали, и над этими кусками уже надо думать мозгой, что делать.
... << RSDN@Home 1.2.0 alpha 4 rev. 1095 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[50]: Куда девать ф-ции внешние для класса
От: Ziaw Россия  
Дата: 28.07.08 23:12
Оценка: +1
Здравствуйте, AndrewVK, Вы писали:


AVK>Что тогда ты пытаешься доказать?

что правило выдуманное IB для улучшения расширяемости может сработать:
1. для ухудшения читабельности кода (занятие бесполезное, поскольку измерить читабельность нечем), а закладываемая расширяемость никогда не появится. (для всех случаев выноса кроме экстеншен методов)
2. для ухудшения расширяемости

AVK>>>Хорошо, тогда следующий вопрос — почему аналогичную ситуацию мы видим в классе Queryable? Ведь IQueryable до этого в фреймворке не было, следовательно никаких проблем с совместимосттью нет?

Z>>Потому, что в случае экземплярной реализации всем реализациям пришлось бы наследоваться от абстрактного класса
AVK>IQueryable, как несложно догадаться из названия, это интерфейс и никакого наследования от абстрактного класса он не требует.
Я в курсе, даже пытался его реализовать.
Имелось в виду, что в случае включения всех методов в контракт интерфейса в каждой реализации пришлось бы либо копипастить имплементацию либо наследоваться от класса где они уже есть.
... << RSDN@Home 1.2.0 alpha 4 rev. 1096>>
Re[51]: Куда девать ф-ции внешние для класса
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 28.07.08 23:17
Оценка: +1
Здравствуйте, Ziaw, Вы писали:

Z>1. для ухудшения читабельности кода


Пример этого не продемонстрировал.

Z> (занятие бесполезное


Ага, особенно если учесть, что код с использванием extension методов идентичен коду использования instance методов вплоть до символа.

Z>2. для ухудшения расширяемости


Пример этого не продемонстрировал.

AVK>>IQueryable, как несложно догадаться из названия, это интерфейс и никакого наследования от абстрактного класса он не требует.

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

Ну вот, ты и сам можешь ответить на свой вопрос, почему раздувание твоего гипотетического ISet — идея совсем не замечательная.
... << RSDN@Home 1.2.0 alpha 4 rev. 1095 on Windows Vista 6.0.6001.65536>>
AVK Blog
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.