Является ли статический класс уместным, когда состояние является неизменным?
Допустим, у меня есть простой класс под названием WebsterDictionary
у него есть функция, которая может взять слово и вернуть его определение. Возможно, есть другая функция, которая может принять определение и вернуть слово. Этот класс постоянно используется многими клиентами.
Для облегчения поиска класс содержит переменную-член, которая представляет собой словарь в памяти, в котором хранятся слова и связанные с ними определения. Предположим, что словарь никогда не может измениться после его инициализации - он постоянен и не будет меняться в разных случаях.
Это хороший кандидат на статический класс? Я читал, что статические классы должны быть без состояний... но у этого класса есть состояние (словарь в памяти), верно?
РЕДАКТИРОВАТЬ: Кроме того, если это становится статическим классом, когда я инициализирую словарь, так как больше не будет конструктор? Нужно ли проверять, является ли ссылка на словарь нулевой каждый раз, когда вызывается один из статических методов?
Благодарю.
8 ответов
Статический класс подходит, когда функциональность не нуждается в замене (например, для тестов). Если вы хотите использовать заглушку или макет, вы должны создать соответствующий интерфейс, а затем реализовать его с помощью синглтона.
Чтобы расширить ответы других, статический класс или синглтон полезен, когда вам нужно иметь только один экземпляр класса. Это гораздо проще сделать, когда данные неизменны. Таким образом, есть вероятность, что статический класс - это то, что вы хотите использовать для этого. Но это не обязательно тот случай, когда это автоматически, что вы хотите использовать.
Мой совет: задайте себе один вопрос: развалится ли мир, если я создам более одного из этих объектов? Если это так, используйте одноэлементный или статический класс. В противном случае используйте обычный класс.
Статический класс может быть тем, что вы хотите здесь (см. Другие ответы). Но не делайте ошибку, называя свой словарь "неизменным".
Неизменяемость не означает "никогда не может измениться во время выполнения" в том смысле, что вы использовали фразу, потому что ваш словарь действительно изменяется во время выполнения; после того, как вы должны создать его, вы также должны добавить элементы. Даже в этот момент вы можете подумать, что это никогда не изменится снова, но это возможно изменить. Ваше намерение нигде не реализовано.
Истинный неизменный объект не может измениться после создания, независимо от того, сколько вы пытаетесь. Вместо этого, когда вам нужен вариант объекта, вы должны создать новый экземпляр с нужными атрибутами.
В каком-то смысле вы можете думать о статическом классе как об одном экземпляре. Вероятно, это не лучший выбор для шаблона, в котором вы зависите от создания новых экземпляров для каждого изменения состояния.
То, что вы ищете, может быть синглтон?
Нет необходимости в том, чтобы у статического класса не было состояния (у него могут быть статические члены, которые могут быть частью его состояния).
Вы можете пойти в Синглтон или в Статический класс. Я бы, наверное, пошел с Синглтоном, но я думаю, что это в основном вопрос предпочтений в этой конкретной ситуации.
Как вы сказали, класс содержит некоторую форму глобального состояния, даже если оно доступно только для чтения. При использовании подхода Singleton становится ясно, что он содержит данные.
Если вы используете инъекцию зависимостей, вы можете сделать так, чтобы она внедряла единичные экземпляры, вместо того, чтобы все классы имели код, который возвращает вас к экземпляру. Это означает, что другие классы не будут привязаны к подходу Singleton, и если вам будет проще заменить его при тестировании (в сочетании с интерфейсом, позволяющим заменить тестовыми макетами).
Это звучит очень похоже на описание модели Monostate: вы хотели бы того же WebsterDictionary
быть общим для всех. Просто так получилось, что WebsterDictionary
также является неизменным, но это ортогональная проблема: просто сделать невозможным обновление (например, с помощью оболочки только для чтения).
Статический класс подходит, когда должен существовать только один "экземпляр", и в этом случае шаблон Singleton может быть или не быть более подходящим (в зависимости от деталей). Для неизменяемого объекта, для которого вам понадобится несколько экземпляров, конечно, статический класс не подходит.