Чи погані непорушні / без громадянства одинаки?


12

Останнім часом відбулася якась революція проти одинаків, але чи з ними щось не так, якщо вони без громадянства?

Я знаю розмови про надмірне використання і все ... це стосується всього лише не одиноких.


1
Ні, одиночні в принципі непогані, їх просто масово використовують.
Барт ван Іґен Шенау

3
що ти маєш на увазі останнім часом?
Маной Р

5
@Joachim Sauer: Навіщо вам потрібно замінити; якщо він є без громадянства, ви можете перевірити це безпосередньо.
m3th0dman

1
Якщо у вас є одиночний стан без громадянства, ви, в основному, маєте статичний клас корисності, який має тенденцію переростати в антидіапазон класу Бог. Зазвичай ви можете використовувати статичні методи замість цього в контексті, в якому вони використовуються (або ще краще: використовувати методи розширення в C #).
Спікей

Відповіді:


12
  > Are immutable/stateless singletons bad?
  • Ні, якщо вони не залежать від інших зовнішніх Систем.
    • Приклад: Stringutility, який уникає html всередині рядка.
    • Причина: В одиничних тестах немає необхідності замінювати це макетом / тренажером.
  • Так, якщо ваш незмінний / без громадянства одиночний залежить від інших зовнішніх систем / служб і якщо ви хочете провести тестування (тестування в ізоляції)
    • Приклад: сервіс, який залежить від зовнішнього податкового калькулятора-веб-сервісу.
    • Причина: для того, щоб проводити тестування з цією службою (ізольовано), ви повинні імітувати / знущатися над зовнішніми системами / службами.

Більш детально див . Лукову архітектуру


  • Singleton-s може зробити тестування блоку (ізольовано) більш чітким / неможливим та
  • приховані залежності / зв'язок можна розглядати як проблему, як пояснив @yBee

Я не бачу інших причин, чому не використовувати Singletons.


Вам все одно доведеться знущатися над цією зовнішньою веб-службою, якщо ви хочете перевірити свій клас, навіть якщо це не сингл без штату.
m3th0dman

@ m3th0dman я згоден
k3b

10

Це завжди залежить від використання. Я думаю , що революція виходить з того, що кожен програміст дізнається цю модель як в об'єктно - орієнтованому візерунок. Більшість забуває думати про те, де це має сенс, а де - ні.
Це, звичайно, справедливо для кожного шаблону. Просто використовуючи шаблони, ви не створюєте хорошого коду чи хорошого програмного забезпечення.

Якщо у вас одиночний стан без громадянства, чому б не використовувати клас, що пропонує лише статичні методи (або використовувати статичний клас)?

Ось декілька публікацій щодо глобальних змінних та одинаків загалом.

Я не був би таким суворим, як автор, але він показує, що для більшості випадків, коли ти думаєш, що тобі потрібен сингл, він насправді не потрібен.


1
Чому б не використовувати клас зі статичними методами? Наслідування, наприклад ...
m3th0dman

3
@ m3th0dman: Це не здається гарним місцем для спадкування.
Біллі ONeal

@BillyONeal Ви можете сказати, що щось є добре чи погано для спадкування, якщо ви знаєте модель домену, що потрібно моделювати таким чином ...
m3th0dman

2
@ m3th0dman: Erm, ні. Я можу бути досить позитивним, нічого не знаючи про доменну модель. Спадщина для поліморфної поведінки. Але як одинокий, у вас не буде поліморфної поведінки.
Біллі ONeal

1
@ m3th0dman: Тому що для отримання об'єкта singleton потрібно вказати ім'я синглтона на сайті виклику. Це означає, що ви не використовуєте поліморфну ​​поведінку. Що означає, що склад набагато гнучкіший, ніж спадкування.
Біллі ONeal

7

Немає нічого непорушного сингла без стану, що статичний клас не може.

Просто немає підстав додавати додатковий рівень складності, який створює -> Instance (), тоді як звичайний виклик статичного методу буде чіткішим, більш консервативним щодо ресурсів і, ймовірно, швидшим.

Справа не в тому, що вони помиляються. Це є кращий спосіб зробити це. Існують сценарії, коли нормальні ("штатні") сингли є правильним шляхом. Зло з одинаком полягає в тому, що їх часто зловживають, мають такі ж погані результати, як і глобальні змінні, але є конкретні випадки, коли використання синглтона є просто правильним. Немає таких випадків для громадян без громадянства.


Надіюсь, ви можете побудувати деякі випадки, коли Сінглтон має деякі переваги. Залежно від сценарію та, можливо, мови програмування (наприклад, скориставшись ледачим завантаженням).
StampedeXV

1
@StampedeXV: Так, великолепний сингл, безумовно. Без громадянства та непорушного - мені дуже цікаво почути будь-які приклади, але я не затримую дихання.
СФ.

Гаразд, у вас є пункт. Я трохи узагальнив вашу відповідь. Для непорушних осіб без громадянства я також не бачу жодної переваги.
StampedeXV

1
З класами, які мають лише статичні функції, ви не можете використовувати успадкування / поліморфізм, який є великою межею ...
m3th0dman

1
Немає нічого непорушного сингла без стану, що статичний клас не може. ну, статичні методи не можуть реалізувати інтерфейс, який міг би синглтон
Michal M

3

Основна проблема синглтона полягає в тому, що він приховує залежності і зв'язок, особливо коли використовується в наскрізних сценаріях. Ознайомтесь із синглонтами патологічними брехунами або Чому Singleton є злом для подальшого читання.

З іншого боку, стан, менший сингл, якщо його не зловживати, може бути корисним та покращити продуктивність. Розглянемо приклад:

interface Interface
{
    void Method();
}

class StatelessSingleton : Interface
{
    public static readonly StatelessSingleton Instance = new StatelessSingleton();
    private StatelessSingleton() { }

    public void Method() { }
}

class User
{
    public User(Interface i) { /* ... */ }
}

Тут StatelessSingleton виконує функцію інтерфейсу за замовчуванням і вводиться в конструктор користувача. Не існує твердо кодованої зв'язку та прихованих залежностей. Ми не можемо використовувати статичний клас через базовий інтерфейс, але немає причин створювати більше ніж один екземпляр за замовчуванням. Ось чому здається, що одноосібник без громадянства є правильним вибором.

Однак, можливо, ми повинні використовувати інший шаблон для реалізації за замовчуванням:

class Implementation : Interface
{
    private readonly Action _method;

    public Implementation()
    {
        _method = new Action(() => { /* default */ });
    }

    public Implementation(Action custom)
    {
        _method = custom;
    }

    public void Method()
    {
        _method();
    }
}

Це вражає продуктивність щодо StatelessSingleton, але є загальною реалізацією інтерфейсу. Аналогічне рішення використовується інтерфейсом IProgress .

Хоча знову ж таки, чому дозволяють створювати більше однієї реалізації поведінки за замовчуванням? Але ми можемо поєднати два:

class Implementation : Interface
{
    public readonly Implementation Default = new Implementation();

    private readonly Action _method;

    private Implementation()
    {
        _method = new Action(() => { /* default */ });
    }

    public Implementation(Action custom)
    {
        _method = custom;
    }

    public void Method()
    {
        _method();
    }
}

На закінчення я вважаю, що є місця (як зображені за замовчуванням), де одиночні корисні. Основне визначення Singleton зазначає, що він забороняє створювати більше одного примірника класу. Це як ядерна енергетика. Може виробляти енергію або бомбу. Це залежить від людини.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.