Разве статические члены сами не создают классы (глобальные) объекты? - PullRequest
4 голосов
/ 03 февраля 2009

Каждый раз, когда я сталкиваюсь с реализацией шаблона синглтона или любых статических классов (то есть классов с (почти) только статическими членами), я задаюсь вопросом, не является ли это на самом деле хаком и, следовательно, серьезным злоупотреблением принципом классов и экземпляров просто для разработки отдельных объектов вместо разработки классов и создания одного экземпляра. Мне кажется, что статические члены классов в целом пытаются добавить какие-то характеристики к классам, которых они на самом деле не должны иметь, и которые скорее заставляют их возражать самим.

Но действительно ли желательно, чтобы отдельные объекты были реализованы таким образом? Или вы видите вещи совершенно иначе и не думаете, что такие статические классы или синглтоны имеют что-то общее с реальными объектами?

Ответы [ 5 ]

7 голосов
/ 03 февраля 2009

Статические члены - это всего лишь пространство имен для глобалов, да. Ничего плохого в этом нет; Пространство имен хорошо, и глобальные переменные - самый чистый способ выполнить некоторые задачи.

Синглеты могут быть несколько более интересными (загрузка по требованию ...), но они похожи на конструкцию (да, вы можете представить статический член как анонимный синглтон, управляемый компилятором).

Как и большинство вещей, эти инструменты имеют свое место, и только идеологи беспокоятся о том, «соответствуют» они или нет конкретной идеологии.

2 голосов
/ 03 февраля 2009

Вы можете просмотреть его с точки зрения производительности и памяти. Например, в следующем коде:

public class StringUtils
{
    public static boolean isEmpty(String value)
    {
        // some code
    }

    public static String reverseString(String value)
    {
        // some code
    }
}

Вы действительно хотите создавать экземпляры объектов StringUtils повсеместно, просто чтобы вызвать метод, который не хранит никаких переменных-членов? В простой программе это не имеет большого значения. Но как только ваша программа начинает достигать определенного размера, и вы вызываете эти методы тысячи раз, ну, давайте просто добавим к ним примеры. И почему? Быть пуристом? Это не стоит затрат. Просто используйте тот же экземпляр.

2 голосов
/ 03 февраля 2009

В зависимости от вашего языка классы являются объектами. В ruby ​​и java они относятся к классу; в питоне я не помню (подклассы типа?).

В java нельзя обойтись без занятий. Это означает, что вам иногда приходится использовать классы, как если бы вы использовали пространства имен и модули. Многие статические методы в Math являются хорошим примером этого. Я бы сказал, что статичность этих методов делает лучшее из плохой ситуации.

Я думаю, что "грязно" иметь статические атрибуты, очень сильно зависит от контекста. То, что вы действительно должны искать, это правильная инкапсуляция: хорошо, если вы можете нарисовать кривую в концептуальном пространстве вашего кода и сказать: «Все на этой стороне не должно ничего знать о вещах на этой стороне, кроме интерфейса через кривая.

1 голос
/ 03 февраля 2009

Скажем, у меня есть приложение, которое имеет один файл конфигурации. Как бы я создал функции для работы с этим файлом без использования «синглтона», если мой язык не поддерживает глобальные функции вне класса (например, Java или C #)?

Мне кажется, что единственный реальный способ достичь этого - это синглтон-класс. Используя шаблон синглтона, вам также не нужно передавать указатель на объект, поскольку вы можете просто использовать статический метод, чтобы получить его снова.

Я не понимаю, как это является нарушением каких-либо принципов ОО. Чтобы сделать это по-другому, например, поместить функции конфигурации в другой класс, который не имеет дело с конфигурацией (например, «служебный» класс), это больше нарушения принципов ОО.

0 голосов
/ 14 января 2011

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

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

С другой стороны, если вы сделаете это:

public enum Data implements MyInterface{
   INSTANCE;
       private final Whatevertype secretstuff = new Whatevertype();
       ...etc...
       public void PutThing( Sometype indata){ ... };
       public Sometype GetThing( int somecode ){ ...};
       ...etc...
 }

Вы (а) не должны ничего создавать и (b) можете получить доступ из любого места с помощью

Data.INSTANCE.GetThing(42);

и т.д.. Это как Горец ... ТОЛЬКО МОЖЕТ БЫТЬ ОДИН

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...