F# мог завоевать популярность, потому что Microsoft продвигает его.
Pro:
Мятежник:
Так, я даю 50:50 шанс F# для становления важным. Другие функциональные языки не собираются делать его в ближайшем будущем.
Согласно партийной линии (Э. Гамма, Р. Хелм, Р. Джонсон и Дж. Влиссидес. Шаблоны проектирования: элементы многоразового объектно-ориентированного программного обеспечения . Addison-Wesley, Reading, MA, 1995, p. 128), синглтон предлагает следующие преимущества по сравнению с решением, которое вы предлагаете.
Сказав это, в большинстве случаев случаях я считаю дополнительную сложность чрезмерной и редко использую шаблон в написанном мной коде. Но я вижу его ценность, когда вы создаете API, который будут использовать другие.
ExpandoObject
относится к DLR и в первую очередь относится к игре между C # и динамическим языком (возможно, IronPython); однако в более общем смысле этот тип объекта property-bag может быть полезен, когда схема ваших типов известна только во время выполнения, возможно, на основе данных базы данных / данных конфигурации. Возможно, это пример анти-шаблона «внутренняя платформа», но он полезен в определенных сценариях для присоединения свойств во время выполнения. Конечно, для использования исключительно CLR (т. Е. Без вызывающих DLR) вы можете сделать это намного проще с помощью индексатора и словаря:
obj["Name"] = "Fred";
string name = (string) obj["Name"];
Для целей привязки данных, даже с этим вы можете добиться полной привязки данных с помощью настраиваемых дескрипторов свойств. через ICustomTypeDescriptor
или TypeDescriptionProvider
.
Или для простого примера:
Конструкция статического синглтона MySingleton;
вызывается при первом использовании. (Когда вызывается get_instance ()
.) Если он никогда не вызывается, он никогда не вызывает конструктор. Ваш метод вызовет конструктор во время статического построения. Предыдущий метод позволяет указать порядок и время вызова конструкторов. Ваш метод упорядочит построение каждого синглтона в соответствии с порядком статической инициализации компилятора.
ABC_ACM_012_username
является подписчиком для ABC_ACM_012
ABC_ACM_012_CAN_username
является подписчиком для ABC_ACM_012_CAN [My 1265749] -121 статическая конструкция [My 126572087] -121 статическая конструкция ;
вызывается при первом использовании. (Когда вызывается get_instance ()
.) Если он никогда не вызывается, он никогда не вызывает конструктор. Ваш метод вызовет конструктор во время статического построения. Предыдущий метод позволяет указать порядок и время вызова конструкторов. Ваш метод упорядочит построение каждого синглтона в соответствии с порядком статической инициализации компилятора.
ABC_ACM_012_username
является подписчиком ABC_ACM_012
ABC_ACM_012_CAN_username
является подписчиком ABC_ACM_012_CAN [My 126571849] -121 статическая конструкция --- ;
вызывается при первом использовании. (Когда вызывается get_instance ()
.) Если он никогда не вызывается, он никогда не вызывает конструктор. Ваш метод вызовет конструктор во время статического построения. Предыдущий метод позволяет указать порядок и время вызова конструкторов. Ваш метод упорядочит построение каждого синглтона в соответствии с порядком статической инициализации компилятора.
get_instance ()
.) Если он никогда не вызывается, он никогда не вызывает конструктор. Ваш метод вызовет конструктор во время статического построения. Предыдущий метод позволяет указать порядок и время вызова конструкторов. Ваш метод упорядочит построение каждого синглтона в соответствии с порядком статической инициализации компилятора. вызывается при первом использовании. (Когда вызывается get_instance ()
.) Если он никогда не вызывается, он никогда не вызывает конструктор. Ваш метод вызовет конструктор во время статического построения. Предыдущий метод позволяет указать порядок и время вызова конструкторов. Ваш метод упорядочит построение каждого синглтона в соответствии с порядком статической инициализации компилятора. Чтобы функции + статические данные имитировали шаблон singleton, нужно полагаться на область видимости файла C ++ и раздельную компиляцию. Это конструкции компилятора, а не языковые конструкции. Шаблон класса singleton допускает инкапсуляцию данных независимо от расположения относительно единиц компиляции; он правильно инкапсулирован, даже если он определен в файле с другими классами и функциями.
Также он фактически не будет имитировать поведение одноэлементного шаблона, а просто статического объекта, что не одно и то же. Синглтон ' Время жизни не зависит от жизни процесса, который его содержит. Правильно сформированный синглтон создается при первом использовании, тогда как статические данные создаются и инициализируются до запуска main (). Это может быть проблемой, если, скажем, создание объекта зависит от существования некоторой другой сущности времени выполнения. Кроме того, одноэлементный объект не занимает никакой памяти (кроме статического указателя экземпляра), пока он не будет создан. Он также может быть уничтожен и воссоздан в любое время, и действительно много раз.
Обратите внимание, если вы измените свой синглтон, чтобы сделать конструктор защищенным, а не закрытым, вы можете создать его подкласс (и, таким образом, легко применить шаблон повторного использования синглтона), вы не можете сделать это со статическим объектом, или объектом со всеми статическими членами, или функциями со статическими данными в области файлов,
Проблема простого использования бесплатных функций заключается в том, что они не по умолчанию получить общее постоянное поведение, такое как ваш одноэлементный класс может получить с переменными-членами и константами.
Вы можете перейти к использованию статических глобальных переменных, чтобы делать то же самое, но для тех, кто пытается это понять, это делает область видимости на что они должны смотреть, чтобы понять поведение этих рутин, почти безгранично. С одноэлементным классом
Лично я использую синглтоны, когда хочу контролировать, когда конструктор выполняется в первый раз.
Например; если у меня есть синглтон для моей системы журналов, код для открытия файла для записи помещается в конструкцию синглтона, которая называется как; Logger.instance (); в моем процессе запуска. Если бы я использовал пространство имен, у меня был бы этот контроль.