Monostate - хороший двоюродный брат злого Синглтона? - PullRequest
7 голосов
/ 09 марта 2009

Синглтон определенно является одним из наиболее часто используемых и злоупотребляемых шаблонов. Многие из нас были заражены синглтонитом в тот или иной момент. Любопытно, что его близкий родственник Моностат менее известен и менее используется. Каково ваше мнение о Monostate? Добро или просто зло? Это лучшая альтернатива использованию Singleton? Вы также не одобрили бы его использование с Singleton?

Ответы [ 8 ]

7 голосов
/ 09 марта 2009

Гм, моностат - это Singleton ... поэтому у него точно такие же проблемы.

  • тестирование
  • скрытие зависимостей
  • негибкий
  • поток безопасности
  • глобальное состояние затрудняет обеспечение правильности
5 голосов
/ 09 марта 2009

Согласно этому определению Monostates , это примечание:

"Моностаты - это зло точно так же, как SingletonsAreEvil ."

Я не обязательно согласен. Основная предпосылка заключается в том, что синглтоны и моностаты являются глобальными переменными, а поскольку глобалы являются злом, то же самое должно быть и синглетонами и моностатами.

Проблема с этой линией рассуждений заключается в том, что она не учитывает, ПОЧЕМУ глобалы злые. Глобалы являются злом прежде всего потому, что они являются переменными, к которым можно получить доступ за пределами локальной области действия случайно , подобно тому, как нетипизированные языки часто позволяют создавать переменные, просто ссылаясь на них.

Одиночные и моностаты не могут вызывать однотипные проблемы, потому что практически невозможно «случайно» сослаться на глобальную статическую переменную, вызвать ее метод экземпляра, а затем использовать экземпляр.

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

Теперь, могут ли синглтоны и моностаты вызывать другие виды проблем? Конечно. Очевидно, что люди из TDD ненавидят их, потому что их сложно правильно протестировать с помощью автоматического тестирования. Хорошо, хорошо, но для тех людей, которые не используют TDD, таких проблем не существует.

Конечно, синглтонами можно злоупотреблять. Люди, которые используют их просто, чтобы избежать передачи экземпляра, злоупотребляют ими. Я думаю, что Monostates лучше для этого, чем синглтон.

Многие люди предлагают фабричные шаблоны вместо одиночных, но я чувствую, что фабрики - это просто модные генераторы-одиночки. Нет, статического метода «экземпляра» не существует, но он в основном делает то же самое (когда фабрика создает один объект экземпляра). Factory.Create ничем не отличается от Singleton.Instance.

EDIT:

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

5 голосов
/ 09 марта 2009

как насчет не использовать шаблоны только потому, что?

обновление: злоупотребление синглтоном происходит потому, что люди добавляют шаблон без обоснования. Это часто добавляет произвольное ограничение к бесполезности. использование monostate без обоснования, возможно, менее вредно, но не более оправдано. если юниверс не рухнет, если существует более одного экземпляра, не используйте его с помощью шаблона - просто создайте только один экземпляр.

4 голосов
/ 09 марта 2009

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

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

4 голосов
/ 09 марта 2009

Почему вы предполагаете, что люди будут препятствовать использованию Singletons? Создание широких обобщений о синглетонах похоже на создание широких обобщений о gotos, глобальных переменных и так далее. Есть место для всех них. Ничто из этого не является «злом», и их неправильное использование не делает их плохими в использовании, это просто означает, что их нужно использовать правильно.

2 голосов
/ 09 марта 2009

Вот выдержка из стр. 127 «Шаблонов проектирования: элементы многоразового объектно-ориентированного программного обеспечения» от Gamma, Helm, Johnson и Vlissides.

Используйте шаблон Singleton, когда

  • должен быть ровно один экземпляр класса, и он должен быть доступен клиентам из известной точки доступа
  • когда единственный экземпляр должен быть расширяемым с помощью подклассов, и клиенты должны иметь возможность использовать расширенный экземпляр без изменения своего кода

Действительно ли это делает синглетонов злыми только потому, что их неправильно используют и неправильно понимают?

1 голос
/ 11 марта 2009

Как насчет класса с одним экземпляром, но без глобального доступа:

public class SingleInstance
{
    private static boolean exhausted = false;

    public SingleInstance()
    {
        if (exhausted)
        {
            throw new IllegalStateException("only one instance allowed");
        }
        exhausted = true;

        [...]
    }

    [...]
}

Это позволяет избежать проблем Singleton и MonoState, а также обеспечивает и четко сообщает, что существует только один экземпляр.

1 голос
/ 09 марта 2009

Сделка с Monostate заключается в том, что вам нужно меньше знать о реализации объекта, чтобы использовать его. Другими словами, вы сохраняете несколько нажатий клавиш, потому что вам не нужно вызывать метод getInstance объектов (Singleton s = Singleton :: getInstance; s.Method ();), чтобы получить ссылку на объект, вы просто используете обычные языковые конструкции (Monostate ms; ms.Method ();). Действительно тонкая грань.

Любая конструкция языка программирования может быть помечена как злая, потому что любое злоупотребление языком программирования может быть нарушено.

При разумном использовании я не вижу ни одного "зла" или "добра".

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