Здравствуйте, dancingintherain, Вы писали:
D>Спасибо.
Вы смешиваете две разные задачи:
1. Иметь по одному экземпляру объекта
2. Избежать дублирования кода
1. Когда у Вас много Singletones по всей программе, это превращается в кошмар, так как складывается ощущение, что они хаотично возникают тут и там. Также нет контроля за временем создания (либо он неполный и затруднен при большом количестве объектов). В этом случае лучше использовать шаблон из Java (не помню, как называется коллеги, напомните), вида Container.GetObject<Type>(), если нужно более глубокий контроль над количеством объектов или их свойствами можно исопльзовать доп аргументы. Хотите скрыть от пользователей — используете internal инициализацию
internal void Container.Add(Object a)
либо стратегию инициализации.
2. Задача "как избежать дублирование кода" зависит от Ваших нужд и решается, например, как уже упоминали, абстрактными классами и наследованием, либо утилитными методами (создаете класс-инструмент, куда включаете общий код, можно со статическими методами).
P.S. В Singleton удобнее использовать свойство Singleton.Instance нежели метод-а-ля-геттер
Здравствуйте, dancingintherain, Вы писали: D>Я реализую алгоритм на основе конечных автоматов, D>синглтоны — это состояния автомата. D>Состояний много, они описываются по нескольку в одном классе. D>И вот когда видишь пять синглтонов, расположенных подряд, с таким дублированием, D>ну оочень хочется это дублирование убрать, ведь это не только лишние строки, D>это еще и затрудняет понимание кода.
Я кажется понял, откуда ноги растут.
Видимо, алгоритм, на основе конечных автоматов вы реализуете с помощью паттерна State, каноническая реализация которого основана на синглтонах для каждого состояния. Если это так, то применение синглтонов бандой четырех основано на том, что реализация приведена на С++, получение полиморфного поведения в котором требует применения указателей (ссылки в данном случае ничего бы не решили). Применение указателей подразумевает динамическое создание объектов, а без автоматического управления памятью наиболее простым способом управления временем жизни каждого состояния является применение синглтонов для каждого экземпляра состояния.
Но даже сегодня в С++ более предпочтительно использовать динамическое создание экземпляра состояния и возврат его с помощью умного указателя, а в C# вообще нет смысла каждое состояние заворачивать в синглтон; можно спокойно каждый раз создавать свой экземпляр состояния (к тому же, в таком случае состояние может содержать некоторые изменяемые переменные состояния, что в случае с синглтоном было бы невозможно).
Здравствуйте, SergeyT., Вы писали:
ST>Для общего сведения: о вреде синглтонов написано не мало, и на этом форуме в том числе. От них не стоит отказываться полностью, но наличие двух десятков синглтонов однозначно говорит о проблемах в дизайне.
Есть только одно оправдание использованию синглтона это необходимость интеграции с существующем кодом который по другому не понимает.
Во всех остальных случаях от синглтона нужно отказываться безусловно ибо я еще не видел долгоживущей программы с синглтонами в которой они не стали бы проблемой.
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, SergeyT., Вы писали:
ST>Я кажется понял, откуда ноги растут. ST>Видимо, алгоритм, на основе конечных автоматов вы реализуете с помощью паттерна State, каноническая реализация которого основана на синглтонах для каждого состояния. Если это так, то применение синглтонов бандой четырех основано на том, что реализация приведена на С++, получение полиморфного поведения в котором требует применения указателей (ссылки в данном случае ничего бы не решили). Применение указателей подразумевает динамическое создание объектов, а без автоматического управления памятью наиболее простым способом управления временем жизни каждого состояния является применение синглтонов для каждого экземпляра состояния. ST>Но даже сегодня в С++ более предпочтительно использовать динамическое создание экземпляра состояния и возврат его с помощью умного указателя, а в C# вообще нет смысла каждое состояние заворачивать в синглтон; можно спокойно каждый раз создавать свой экземпляр состояния (к тому же, в таком случае состояние может содержать некоторые изменяемые переменные состояния, что в случае с синглтоном было бы невозможно).
Да, действительно, это шаблон стэйт.
А вот по поводу "спокойно каждый раз создавать свой экземпляр", мне кажется, что это дело вкуса.
Я не испытываю предубеждений к синглтонам), их использование, мне кажется оправданным, когда не нужно иметь
более одного экземпляра класса.
А вот создание нового экземпляра, когда он уже создан, вызывает у меня ощущение кривости кода, хотя в целом
решение тоже имеет право на существование.
Я ничего не смешиваю.
Изначальная задача была убрать дублирование кода и улучшить его информативность при чтении.
Синглтоны появились как вариант решения этой задачи.
В итоге я отказался от синглтонов и использую фабрику классов, но только потому что мою идею не удалось реализовать
без рефлекшна.
Я не часто использовал синглтоны раньше и, возможно, поэтому еще не проникся всеобщей ненавистью к ним)
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, SergeyT., Вы писали:
ST>>Для общего сведения: о вреде синглтонов написано не мало, и на этом форуме в том числе. От них не стоит отказываться полностью, но наличие двух десятков синглтонов однозначно говорит о проблемах в дизайне. WH>Есть только одно оправдание использованию синглтона это необходимость интеграции с существующем кодом который по другому не понимает. WH>Во всех остальных случаях от синглтона нужно отказываться безусловно ибо я еще не видел долгоживущей программы с синглтонами в которой они не стали бы проблемой.
Я с синглтонами редко вообще встречался,
но всеобщая ненависть к ним, которую я здесь увидел, меня заинтересовала
Надо почитать за что их так не любят)
А может просто использовать Unity?
public static IObject INSTANCE
{
get { return UnityHelper.GetFactoryContainer().Resolve<IObject>(); }
}
Вот так это выглядит у нас
Здравствуйте, Хэлкар, Вы писали:
Х>А может просто использовать Unity? Х> public static IObject INSTANCE Х> { Х> get { return UnityHelper.GetFactoryContainer().Resolve<IObject>(); } Х> } Х>Вот так это выглядит у нас
Да, в итоге я использую что-то подобное, только самодельное.
Сейчас мне это кажется оптимальным решением.