Как одноэлемент отличается от класса, заполненного только статическими полями?
В чем разница между шаблоном Singleton и статическим классом в Java?
Ответ 1
Почти каждый раз, когда я пишу статический класс, я в конечном итоге желаю, чтобы я реализовал его как нестатический класс. Рассмотрим:
- Нестатический класс может быть расширен. Полиморфизм может сэкономить много повторений.
- Нестатический класс может реализовать интерфейс, который может пригодиться, когда вы хотите отделить реализацию от API.
Из-за этих двух точек нестатические классы позволяют писать более надежные модульные тесты для элементов, которые зависят от них, между прочим.
Одноэлементный шаблон всего лишь на полшага от статических классов. Вы можете получить эти преимущества, но если вы обращаетесь к ним непосредственно в других классах с помощью класса ClassName.Instance, вы создаете препятствие для доступа к этим преимуществам. Как указано в ph0enix, вам гораздо лучше использовать шаблон инъекции зависимостей. Таким образом, инфраструктуре DI можно сказать, что конкретный класс является (или нет) синглом. Вы получаете все преимущества от насмешек, модульного тестирования, полиморфизма и гораздо большей гибкости.
Ответ 2
Позвольте мне подвести итог:)
Существенное различие заключается в следующем: форма существования одноэлементного объекта является объектом, а static - нет. Это привело к следующим вещам:
- Singleton может быть расширен. Статический не.
- Создание Singleton может быть небезопасным, если оно не выполнено должным образом. Статический не.
- Синглтон можно передавать как объект. Статический не.
- Синглтон может быть собран в мусор. Статический не.
- Синглтон лучше статического класса!
- Больше здесь, но я еще не понял:)
И последнее, но не менее важное: всякий раз, когда вы собираетесь внедрять синглтон, подумайте о том, чтобы перепроектировать идею о том, что вы не используете этот объект Бога (поверьте, вы склонны вкладывать все "интересные" вещи в этот класс) и использовать нормальный класс с именем "Контекст" или что-то в этом роде.
Ответ 3
Синтаксис может быть инициализирован лениво, для одного.
Ответ 4
Разница не зависит от языка. Singleton по определению: "Убедитесь, что класс имеет только один экземпляр и предоставляет глобальную точку доступа к нему". Класс, заполненный только статическими полями, не такой же, как singleton, но, возможно, в вашем сценарии использования они обеспечивают ту же функциональность. Но, как сказал JRL, ленивая инициация - это одно отличие.
Ответ 5
Я думаю, что значительная вещь - это "объект" в объектно-ориентированном программировании. За исключением нескольких случаев, мы должны ограничивать использование статических классов. Это следующие случаи:
- Когда создание объекта бессмысленно. Как и методы java.lang.Math. Мы можем использовать класс как объект. Поскольку поведение методов класса Math не зависит от состояния объектов, которые должны быть созданы в этом классе.
- Коды, которые будут использоваться совместно более чем одним объектным методом, коды, которые не достигают объектных переменных и могут быть закрыты, могут быть статическими методами.
Еще одна важная вещь - синглтон расширяемый. Singleton может быть расширен. В классе Math, используя конечные методы, было предотвращено создание и расширение объекта этого класса. То же самое относится к классу java.lang.System. Однако класс Runtime является единственным объектом, а не статическим методом. В этом случае вы можете переопределить методы наследования класса Runtime для разных целей.
Вы можете отложить создание объекта Singleton до тех пор, пока он не понадобится (ленивая загрузка). Однако для статических классов методов нет такой вещи, как условие. Если вы достигнете какого-либо статического члена класса, класс будет загружен в память.
В результате самым основным преимуществом для класса статических методов является то, что вам не нужно создавать объект, но при неправильном использовании он удалит ваш код из объектно-ориентированного.
Ответ 6
По крайней мере, вы можете легко заменить его макетом или заглушкой для модульного тестирования. Но я не большой поклонник синглтонов именно по той причине, которую вы описываете: это маскирующие переменные.
Ответ 7
Singleton - это класс с одним экземпляром, принудительным. У этого класса может быть состояние (да, я знаю состояние сохранения статических переменных), не все переменные-члены или методы должны быть статическими.
Вариантом будет небольшой пул этих объектов, что было бы невозможно, если все методы были статическими.
Ответ 8
В одноэлементном классе будет экземпляр, который, как правило, один и только один для каждого загрузчика классов. Таким образом, он может иметь обычные методы (не статические), и их можно вызвать в этом конкретном экземпляре.
В то время как класс с только статическими методами, нет необходимости создавать экземпляр (по этой причине большинство людей/фреймворков делают эти классы классов Util абстрактными). Вы просто вызовете методы непосредственно в классе.
Ответ 9
Первое, что приходит в голову, это то, что если вы хотите использовать класс только с статическими методами и атрибутами, а не с singleton, вам придется использовать статический инициализатор для правильной инициализации определенных атрибутов. Пример:
class NoSingleton {
static {
//initialize foo with something complex that can't be done otherwise
}
static private foo;
}
Это будет выполняться в момент загрузки класса, который, вероятно, не тот, который вы хотите. У вас есть больше контроля над всем этим shebang, если вы реализуете его как синглтон. Однако я думаю, что использование синглтонов в любом случае не является хорошей идеей.
Ответ 10
ПРИМЕЧАНИЕ. Примеры приведены на С#, так как это то, чем я больше знаком, но концепция должна применяться к Java точно так же.
Игнорируя дискуссию о том, когда целесообразно использовать объекты Singleton, одним из основных различий, о которых я знаю, является то, что у объекта Singleton есть экземпляр, который вы можете передать.
Если вы используете статический класс, вы прочно привязываетесь к определенной реализации, и нет способа изменить его поведение во время выполнения.
Плохой дизайн с использованием статического класса:
public class MyClass
{
public void SomeMethod(string filename)
{
if (File.Exists(filename))
// do something
}
}
В качестве альтернативы вы могли бы использовать свой конструктор вместо экземпляра определенного интерфейса. В производстве вы можете использовать реализацию Singleton этого интерфейса, но в модульных тестах вы можете просто издеваться над интерфейсом и изменять его поведение, чтобы удовлетворить ваши потребности (например, это заставило его создать неясное исключение).
public class MyClass
{
private IFileSystem m_fileSystem;
public MyClass(IFileSystem fileSystem)
{
m_fileSystem = fileSystem;
}
public void SomeMethod(string filename)
{
if (m_fileSystem.FileExists(filename))
// do something
}
}
Это не означает, что статические классы ВСЕГДА плохи, просто не отличный кандидат на такие вещи, как файловые системы, соединения с базой данных и другие зависимости нижнего уровня.
Ответ 11
Одним из основных преимуществ синглтонов является то, что вы можете реализовать интерфейсы и наследовать от других классов. Иногда у вас есть группа синглтонов, которые обеспечивают аналогичную функциональность, которую вы хотите реализовать с помощью общего интерфейса, но отвечаете за другой ресурс.
Ответ 12
Синглтон Класс: Singleton Class - класс, из которого может существовать только один экземпляр для каждого загрузчика классов.
Класс помощника (класс с только статическими полями/методами): Никакого экземпляра этого класса не существует. Только поля и методы могут быть напрямую доступны как константы или вспомогательные методы.
Эти несколько строк из этого блог прекрасно описывают:
Во-первых, шаблон Singleton очень полезно, если вы хотите создать экземпляр класса. Для моего помощника класс, который мы действительно не хотим создать экземпляр любой копии класса. Причина, по которой вы не должны использовать Класс Singleton - это потому, что для этого вспомогательный класс мы не используем переменные. Одиночный класс быть полезными, если он содержит набор переменные, которые нам нужны только один набор и методы, используемые переменных, но в нашем вспомогательном классе мы не используйте никаких переменных, кроме (которые мы делаем окончательно). По этой причине я не считаю, что мы хочу одиночный экземпляр, потому что мы не нужны переменные, и мы не хотите, чтобы кто-нибудь из вас начал этот класс. Поэтому, если вы не хотите, чтобы кто-либо создание экземпляра класса, который обычно, если у вас есть какие-то helper/utils, тогда я использую то, что Я называю статический класс, класс с частный конструктор и только состоит из статических методов без каких-либо любые переменные.