metaclass: (Default)
[personal profile] metaclass
https://github.com/SparkViewEngine/spark/blob/master/src/Samples/DirectUsage/ConsoleTemplating/Services/MessageBuilder.cs

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

Date: 2014-05-19 07:05 pm (UTC)
From: [identity profile] vp.livejournal.com
Красивый код.

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

public readonly MessageBuilder Instance = new DefaultMessageBuilder()

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

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

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

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

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

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

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

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

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

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

Date: 2014-05-23 04:02 pm (UTC)
From: [identity profile] viacheslav ivanov (from livejournal.com)
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.…

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

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

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

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

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

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

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

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

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

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

Date: 2014-05-19 07:22 pm (UTC)
From: [identity profile] blackyblack.livejournal.com
Такой код очень распространён. По сути это обычный сишный модуль: разово инициализируемый и глобально доступный.

Date: 2014-05-19 07:27 pm (UTC)
From: [identity profile] mr-st.livejournal.com
Интерлокед там нафиг не нужен, кстати.

Date: 2014-05-19 07:37 pm (UTC)
From: [identity profile] metaclass.livejournal.com
Присваивание и проверка для ссылок атомарны?

Date: 2014-05-19 07:38 pm (UTC)
From: [identity profile] mr-st.livejournal.com
Присваивание статику да.

Date: 2014-05-19 07:50 pm (UTC)
From: [identity profile] jakobz.livejournal.com
Кстати от вероятности создать DefaultMessageBuilder два раза, автор кода не защитился.

Date: 2014-05-19 07:41 pm (UTC)
From: [identity profile] mr-st.livejournal.com
Хотя я не совсем прав. Вот такое точно безопасно
class A
{
private static A _instance = new A();
}

Date: 2014-05-19 07:41 pm (UTC)
From: [identity profile] max630.livejournal.com
зачем конкретно вот это вообще виртуализовать?

Date: 2014-05-19 07:45 pm (UTC)
From: [identity profile] max630.livejournal.com
А по теме - если, там есть именно public set {}, а не internal, с проковырянной дырочкой специально для юниттестов - подозреваю какую-то херню, которую можно было бы с трешем сделать

Date: 2014-05-19 08:01 pm (UTC)
From: [identity profile] maxdz.livejournal.com
Не очень ясно, почему в коде по ссылке должен быть синглтон, если у него нет внутреннего состояния. Достаточно было сделать 1 статическую функцию "трансформ".

А так, лично я не фанат синглтонов, из-за их глобальной видимости и их "синглтоновости". :) Сколько ими не пользовался, всегда наступал момент, когда приходилось создавать несколько объектов, вместо 1 - после этого, приходилось переделывать их в нормальные классы и это лишь улучшало общий дезайн.

Date: 2014-05-19 08:05 pm (UTC)
From: [identity profile] maxdz.livejournal.com
>почему в коде по ссылке должен быть синглтон, если у него нет внутреннего состояния

Хотя, если для полиморфного использования... - но это уже для продвинутых извращенцев. :)

Date: 2014-05-20 02:41 pm (UTC)
From: [identity profile] permea-kra.livejournal.com
А за синглетоны как явление еще не принято сажать на кол?

Date: 2014-05-20 03:24 pm (UTC)
From: [identity profile] metaclass.livejournal.com
Принято сажать на кол за втаскивание IoC контейнеров туда, где хватит одного класса и одной статик переменной :)

Date: 2014-05-20 05:10 pm (UTC)
From: [identity profile] vp.livejournal.com
Обоснуете почему?

Date: 2014-05-20 06:07 pm (UTC)
From: [identity profile] metaclass.livejournal.com
Синглетон один на весь процесс, а внезапно может оказаться что нужно несколько экземпляров такого класса, при этом переделать полсистемы, которая уже ссылается на него и протащить нужный экземпляр явно - это печаль.
Я вспомнил несколько мест, где у нас такое может боком вылезти - например, если мы более одного веб-сервиса возжелаем сунуть в один процесс - у них окажутся общие ссылки на некоторые внутренние сервисы и это будет плохо.

Date: 2014-05-20 06:29 pm (UTC)
From: [identity profile] vp.livejournal.com
Не, енто понятно. Но он же потому так и называется. Его использование быть оправдано, может быть нет. Например, логгер, он может быть архитектурно один на все приложение.

Date: 2014-05-20 08:04 pm (UTC)
From: [identity profile] permea-kra.livejournal.com
>Например, логгер, он может быть архитектурно один на все приложение.

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

В целом, единственной причиной для существования синглтонов мне видится неготовность народа таскать состояние явно. В то же время сам факт допущения использования синглтонов неизбежно создает риск ситуаций, описанных ребе Метаклассом.
Edited Date: 2014-05-20 08:28 pm (UTC)

Date: 2014-05-20 08:35 pm (UTC)
From: [identity profile] vp.livejournal.com
При нормальной архитектуре нет никаких проблем, допустим, через параметры конструкторов классов передавать нужные экземпляры классов. Но с другой стороны это может загромождать инициализацию, когда тебе нужно передать n+1 разных контекстов, без которых никак. :)

Date: 2014-05-20 08:42 pm (UTC)
From: [identity profile] permea-kra.livejournal.com
В указанной ситуации вполне можно использовать фабрики классов, в которые можно положить n+m контекстов заранее.

Date: 2014-05-20 08:49 pm (UTC)
From: [identity profile] metaclass.livejournal.com
Ад паттернов. :)

Date: 2014-05-20 08:53 pm (UTC)
From: [identity profile] permea-kra.livejournal.com
Переходите на хаскель =).

Date: 2014-05-20 08:51 pm (UTC)
From: [identity profile] vp.livejournal.com
Имхо наименее симпатичное из решений.

Date: 2014-05-20 08:53 pm (UTC)
From: [identity profile] permea-kra.livejournal.com
Оно зато работает и не вызывает проблем. Если так уж не хочется таскать контексты явно.

Date: 2014-05-20 08:54 pm (UTC)
From: [identity profile] vp.livejournal.com
А в какой момент вы предлагаете доставать мой контекст из общей фабрики? До вызова конструктора, затем передавая его в конструктор, или в самом конструкторе?
И что будет ключом в том и ином случае?

Date: 2014-05-20 08:59 pm (UTC)
From: [identity profile] metaclass.livejournal.com
Причем тут ключ воще? Фабрика это условно говоря класс с десятком полей ссылающихся на куски контекста и одним методом типа "CreateЧегоНибудь" вызывающим конструктор с передачей в него контекстов.
Меня этот вариант тащемта напрягает адом паттернов, написанием классов ради того чтобы писать классы.

Date: 2014-05-20 09:03 pm (UTC)
From: [identity profile] permea-kra.livejournal.com
Да мне самому не нравится. Я б предпочел пропихивать контексты явно, если лень писать полный список каждый раз - предоставить возможность завернуть их в какой-то обертке и пропихивать в конструктор получившийся кулек. Ну или еще лучше - использовать монадки.

Date: 2014-05-20 09:00 pm (UTC)
From: [identity profile] permea-kra.livejournal.com
В описанной ситуации я бы таскал в объекте ссылку на фабрику, переданную в конструкторе.

Но это, понятное дело, разговоры в пользу бедных, поскольку какая инфраструктура сложилась, с такой и придется жить. XML-парсер, например, свой писать никому не хочется.

Profile

metaclass: (Default)
metaclass

April 2017

S M T W T F S
      1
2345678
9101112 131415
16171819202122
23242526272829
30      

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Sep. 7th, 2025 04:20 am
Powered by Dreamwidth Studios