metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2014-05-19 09:42 pm

Синглетоны

https://github.com/SparkViewEngine/spark/blob/master/src/Samples/DirectUsage/ConsoleTemplating/Services/MessageBuilder.cs

А вот насколько подобный код (статик _instance и его инициализация) является кошерным? Ну с interlocked все более-менее понятно, а вот собственно использование синглетонов вместо всяких модных IoC и тому подобного усложняющего все трэша?

[identity profile] jakobz.livejournal.com 2014-05-19 07:21 pm (UTC)(link)
Это какой-то вариант синглтона с дабл-локом - который весьма распространен, видимо с явы какой-нибудь скопирован. Многие не шарят что в дотнете можно делать тупо так:

public readonly MessageBuilder Instance = new DefaultMessageBuilder()

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

Но всё это волнует это только молодежь, которым важно лиду показать "смотри, я дабл-лок умею! Читал умную книжку недавно". Я лично пишу в одну строчку, и мне пофигу.

По поводу IoC и прочих фабрик - оно хорошо только там где оно точно надо. Потому что фабрика, которая может создавать более одного вида инстансов - она сразу, например, делает предельно сложным понимание без дебаггера что откуда вызывается. Типа go to definition делаешь - а там интерфейс или абстрактный класс. А учитывая как жидко в ООП текут абстракции тупых ООП-шников, ихний пустой интерфейс как-то не греет душу.

Я лично прошел как минимум один диалектический цикл - раньше использовал IoC без фанатизма, теперь же предпочитаю хардкодить всё до упора, включая даже большинство настроек. Проще максимально упростить деплой компилированного кода, чем менять в бою разлапистый XML со встроеными убогими eDLS-ями.

[identity profile] jakobz.livejournal.com 2014-05-19 07:28 pm (UTC)(link)
А если уж хочется точно контроллировать когда инстанс поднимется - можно так:
private static readonly Lazy<Singleton> instance = new Lazy<Singleton>(() => new Singleton());

public static Singleton Instance
{
    get { return instanceHolder.Value; }
}

В общем я не могу придумать когда может потребоваться дабл-лок вручную.

[identity profile] aamonster.livejournal.com 2014-05-21 02:12 pm (UTC)(link)
А напомните - в C# static initialization order fiasco остался или как-то регламентирован порядок создания объектов?

[identity profile] berezovsky.livejournal.com 2014-05-21 02:22 pm (UTC)(link)
в стандарте не определён, по факту по тексту класса идёт

[identity profile] metaclass.livejournal.com 2014-05-21 02:50 pm (UTC)(link)
В одном классе хз, в разных - все как положено, по зависимостям.

[identity profile] viacheslav ivanov (from livejournal.com) 2014-05-23 04:02 pm (UTC)(link)
10.5.5.1 Static field initialization
The static field variable initializers of a class correspond to a sequence of assignments that are executed in the textual order in which they appear in the class declaration. .…

10.12 Static constructors
…It is possible to construct circular dependencies that allow static fields with variable initializers to be observed in their default value state.…

Выделение жирным моё.

[identity profile] bydlorus.livejournal.com 2014-05-19 07:30 pm (UTC)(link)
Поэтому вместо go to definition нужно юзать go to implementation, а кто не любит Resharper - Find references.

Но это не возражение, там, мелочная заметка.

[identity profile] jakobz.livejournal.com 2014-05-19 07:40 pm (UTC)(link)
Когда реализаций две или более, и они выбираются, например, из конфигурации в базе - там никакой go to implementation не поможет. Либо раскуривать как фабрика работает и смотреть что в конфиге, либо запускать дебаггер. Второе, как показывает практика - быстрее и надежнее.

По-факту, конечно, IoC с фабриками юзают подрастающие ООП-шники - просто для красоты. Типа вместо 2+2 - херакс, и пять классов с интерфейсами и XML-комментариями. И вроде работы много сделал, и выглядит умно, и законодательно говнокодом назвать нельзя - ведь так делать завещали GoF, Фаулер, и прочие фашисты. Сказать что они неправы - это пойти против enterprise-религии.

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

[identity profile] bydlorus.livejournal.com 2014-05-19 08:29 pm (UTC)(link)
У меня сложилось ощущение, что в это треде мы обсуждаем ненужность интерфейсов и абстракции. Т.е. очевидную ересь.

[identity profile] metaclass.livejournal.com 2014-05-19 07:36 pm (UTC)(link)
Ясно, я почти все нужные мне зависимости тащу вручную, передаю в конструктора. Но кое-где в фреймворках сторонних сидит IoC и можно убится с ним.

[identity profile] jakobz.livejournal.com 2014-05-19 07:56 pm (UTC)(link)
В сторонних фреймворках - оно обычно к лучшему. Всяко не хардкод - хоть подлезть можно. Бесит только если они заставляют всякое ихнее говно куда-нибудь в конфиг писать. Если из кробки запускается в пару строк, но если нужно - можно влезть - то я лично не против совсем.

[personal profile] leotsarev 2014-05-23 08:08 pm (UTC)(link)
Ну тащемта передать все зависимости в конструктор — это IoC. Нехипстерский, но вполне себе IoC.