Re[11]: Наследование или фабрика ?
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 27.02.17 19:53
Оценка: +3
Здравствуйте, Gattaka, Вы писали:

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


Это очень смелое утверждение. Андрей Акиньшин недавно показал, когда это может произойти, но я не помню как-то кейсов, когда проверка статического конструктора *настолько* влияла на производительность end-2-end приложения, чтобы нужно было менять дизайн, чтобы обойти это дело.

И да, "достаточно" закоммитить Thread.Sleep в 73-х местах и любое приложение будет тормозным. Будет проблема, будет профилирование и будет решение. Сильно много future proofing-а в предыдущем абзаце.

Я как-то уже писал об этом в сообщении Статические методы в любом их обличии это зло!
Автор: SergeyT.
Дата: 25.10.13
и готов повторить: статические методы — это не хорошо или плохо. Статические методы с побочными эффектами — чистое зло, а чистые статические методы — это просто прекрасно, ибо их проще читать, тестить и реюзать. И ООП embrace-ит это не хуже ФП, пусть и ничего не гарантирует. Если же именно этот факт кого-то пугает (что ведь можно что-то поменять, и все сломать), то как тогда вообще жить? ведь кто-то может получить доступ через рефлексию к типу вашего массива и сменить его тип во время исполнения? Все, что угодно можно использовать неправильно и вопрос лишь в том, насколько это легко сделать? С моей колокольни использовать неправильно контейнер легче, чем использовать неверно статический метод, ибо первое — это один большой стейт и god-object, а второй — это примитив из которого строится функциональность приложения.
Re: Наследование или фабрика ?
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.03.17 04:07
Оценка: 48 (1) +2
Здравствуйте, _NN_, Вы писали:
_NN>У второго варианта удобнее использование, ведь X,Y будут скрыты от глаз, зато первый вариант не создает ненужного наследования.
Как правило, если у вас возникает вот такой вот "популярный алиас", то недалеко и то время, когда он станет отличаться от от предка.
Поэтому введение алиаса типа NameValueCollection: Dictionary<string, string> оправдано.
Дело не в том, скрыты ли от глаз X и Y. А в том, как вы выражаете требования — если у вас какой-то метод принимает Dictionary<string, string>, то он не вправе ожидать, скажем, case-insensitive сравнения ключей.
Даже если вы сделаете фабрику NameValueCollection с методом Create(), который верно проинициализирует предка, то нет способа потребовать в аргументах именно такой объект.
А как только вы объявили свой NameValueCollection, то тут же получаете возможность явно требовать именно его и полагаться на консистентную инициализацию (а в будущем — и на какие-то дополнительные инварианты, которые вы обеспечите перекрытием унаследованных методов и другим нетривиальным кодом).
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Наследование или фабрика ?
От: Gattaka Россия  
Дата: 01.03.17 05:04
Оценка: +1 -1
Здравствуйте, Sinclair, Вы писали:

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

_NN>>У второго варианта удобнее использование, ведь X,Y будут скрыты от глаз, зато первый вариант не создает ненужного наследования.
S>Как правило, если у вас возникает вот такой вот "популярный алиас", то недалеко и то время, когда он станет отличаться от от предка.
S>Поэтому введение алиаса типа NameValueCollection: Dictionary<string, string> оправдано.
S>Дело не в том, скрыты ли от глаз X и Y. А в том, как вы выражаете требования — если у вас какой-то метод принимает Dictionary<string, string>, то он не вправе ожидать, скажем, case-insensitive сравнения ключей.
S>Даже если вы сделаете фабрику NameValueCollection с методом Create(), который верно проинициализирует предка, то нет способа потребовать в аргументах именно такой объект.
S>А как только вы объявили свой NameValueCollection, то тут же получаете возможность явно требовать именно его и полагаться на консистентную инициализацию (а в будущем — и на какие-то дополнительные инварианты, которые вы обеспечите перекрытием унаследованных методов и другим нетривиальным кодом).

Основная странность здесь в стремлении скрыть X и Y. Это как бы намекает, что зря сделали дженерик если возникает такое желание скрыть.
Re[3]: Наследование или фабрика ?
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.03.17 11:21
Оценка:
Здравствуйте, Gattaka, Вы писали:

G>Основная странность здесь в стремлении скрыть X и Y. Это как бы намекает, что зря сделали дженерик если возникает такое желание скрыть.

Не уверен, что изначальная формулировка верна. Прямо "скрыть скрыть" всё равно не получится — скорее всего, речь о том, чтобы а) убрать с видного места (Кого там интересует, что мы наследуемся от IReadWriteOperations<T>, где T — это CustomerOperationsAbstract<Arithmetic<BigInt>, RetryLogic.ExponentialRetryLogic>>) и б) прекатить обязать всё это выписывать при каждом использовании.

Так-то никаких проблем нету — очень часто "частные специфичные" вещи очень похожи (до неотличимости) на удобный дженерик.
Ну вот из простейшего — целочисленный Random изоморфен IEnumerable<int>.
Но это же не означает, что IEnumerable<int> зря объявлен дженериком.
Тем не менее, если я пишу какой-то код, который может работать с разными генераторами ПСЧ, то лучше его типом параметра всё же взять IRandomSequenceProvider, даже если этот интерфейс ничего не добавляет к базовому для него IEnumerable<int>. Просто из соображений коммуникации — чтобы избежать искушения скормить в мой крипто-модуль формально подходящий параметр вроде {0,}
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.