Разница между статическим классом и одноэлементным шаблоном? - PullRequest
1646 голосов
/ 06 февраля 2009

Какая реальная (то есть практическая) разница существует между статическим классом и одноэлементным шаблоном?

Оба могут быть вызваны без создания экземпляров, оба предоставляют только один «Экземпляр», и ни один из них не является поточно-ориентированным. Есть ли другая разница?

Ответы [ 36 ]

20 голосов
/ 24 апреля 2014

Вот хорошая статья: http://javarevisited.blogspot.com.au/2013/03/difference-between-singleton-pattern-vs-static-class-java.html

Статические классы

  • класс, имеющий все статические методы .
  • лучшая производительность (статические методы связаны во время компиляции)
  • не может переопределять методы, но может использовать скрытие методов. ( Что такое скрытие методов в Java? Даже объяснение JavaDoc сбивает с толку )

    public class Animal {
        public static void foo() {
            System.out.println("Animal");
        }
    }
    
    public class Cat extends Animal {
        public static void foo() {  // hides Animal.foo()
            System.out.println("Cat");
        }
    }
    

Singleton

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


редактирует

17 голосов
/ 16 августа 2009

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

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

редактирование:
Сейчас я на самом деле думаю, что еще одно отличие состоит в том, что класс Static создается при запуске программы * и живет в течение всего жизненного цикла программы, в то время как синглтон явно создается в какой-то момент и может быть уничтожен также.

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

15 голосов
/ 10 июня 2013

Чтобы проиллюстрировать точку зрения Джона, то, что показано ниже, невозможно, если Logger был статическим классом. Класс SomeClass ожидает, что экземпляр реализации ILogger будет передан в его конструктор.

Класс Singleton важен для внедрения зависимости.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {

            var someClass = new SomeClass(Logger.GetLogger());
        }


    }

    public class SomeClass 
    {
        public SomeClass(ILogger MyLogger)
        {

        }
    }

    public class Logger : ILogger
    {
        private static Logger _logger;
        private Logger() { }

        public static Logger GetLogger()
        {
            if (_logger==null)
            {
                _logger = new Logger();
            }

            return _logger;
        }

        public void Log()
        {

        }

    }


    public interface ILogger
    {
         void Log();
    }
}
11 голосов
/ 06 февраля 2009

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

Edit:
Описание правила производительности FxCop: «Методы, которые не обращаются к данным экземпляра или к методам экземпляра вызова, могут быть помечены как статические (Shared в VB). После этого компилятор будет выдавать не виртуальные сайты вызовов этим членам, что предотвратит проверку во время выполнения для каждого вызова, который гарантирует, что текущий указатель объекта не равен нулю. Это может привести к ощутимому приросту производительности для чувствительного к производительности кода. В некоторых случаях невозможность доступа к текущему экземпляру объекта представляет проблему правильности. "
На самом деле я не знаю, относится ли это также к статическим методам в статических классах.

9 голосов
/ 06 февраля 2009

Синглтоны создаются, только один экземпляр когда-либо создавался, следовательно, сингл в синглтоне.

Статический класс не может быть создан чем-либо, кроме себя самого.

6 голосов
/ 13 апреля 2014

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

В примере ниже я проиллюстрирую это. Предположим, у вас есть метод isGoodPrice (), который использует метод getPrice (), и вы реализуете getPrice () как метод в одиночном коде.

синглтон, обеспечивающий функциональность getPrice:

public class SupportedVersionSingelton {

    private static ICalculator instance = null;

    private SupportedVersionSingelton(){

    }

    public static ICalculator getInstance(){
        if(instance == null){
            instance = new SupportedVersionSingelton();
        }

        return instance;
    }

    @Override
    public int getPrice() {
        // calculate price logic here
        return 0;
    }
}

Использование getPrice:

public class Advisor {

    public boolean isGoodDeal(){

        boolean isGoodDeal = false;
        ICalculator supportedVersion = SupportedVersionSingelton.getInstance();
        int price = supportedVersion.getPrice();

        // logic to determine if price is a good deal.
        if(price < 5){
            isGoodDeal = true;
        }

        return isGoodDeal;
    }
}


In case you would like to test the method isGoodPrice , with mocking the getPrice() method you could do it by:
Make your singleton implement an interface and inject it. 



  public interface ICalculator {
        int getPrice();
    }

Окончательная реализация Singleton:

public class SupportedVersionSingelton implements ICalculator {

    private static ICalculator instance = null;

    private SupportedVersionSingelton(){

    }

    public static ICalculator getInstance(){
        if(instance == null){
            instance = new SupportedVersionSingelton();
        }

        return instance;
    }

    @Override
    public int getPrice() {
        return 0;
    }

    // for testing purpose
    public static void setInstance(ICalculator mockObject){
        if(instance != null ){
instance = mockObject;
    }

тестовый класс:

public class TestCalculation {

    class SupportedVersionDouble implements ICalculator{
        @Override
        public int getPrice() { 
            return 1;
        }   
    }
    @Before
    public void setUp() throws Exception {
        ICalculator supportedVersionDouble = new SupportedVersionDouble();
        SupportedVersionSingelton.setInstance(supportedVersionDouble);

    }

    @Test
    public void test() {
          Advisor advidor = new Advisor();
          boolean isGoodDeal = advidor.isGoodDeal();
          Assert.assertEquals(isGoodDeal, true);

    }

}

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

6 голосов
/ 28 апреля 2018

Основные отличия:

  • Синглтон имеет экземпляр / объект, в то время как статический класс является связкой статические методы
  • Синглтон может быть расширен, например, через интерфейс в то время как статический класс не может быть.
  • Синглтон может быть унаследован, что поддерживает принципы открытия / закрытия в Принципы SOLID с другой стороны, статический класс не может быть унаследован и нам нужно внести изменения в себя.
  • Объект Singleton может быть передан методам, в то время как статический класс не имеет экземпляра, который не может быть передан в качестве параметров
6 голосов
/ 11 февраля 2016

Я согласен с этим определением:

Слово " single " означает один объект на протяжении всей жизни приложения. цикл, поэтому сфера находится на уровне приложения.

статический не имеет любой указатель объекта, поэтому область действия находится на уровне домена приложения.

Более того, оба должны быть реализованы как поточно-ориентированные.

Вы можете найти другие интересные отличия: Шаблон Singleton и статический класс

5 голосов
/ 27 июня 2012

Одним заметным отличием является различное воплощение, которое поставляется с синглетонами.

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

4 голосов
/ 27 июня 2012

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

В c # статический класс не может реализовать интерфейс. Когда одному классу экземпляра необходимо реализовать интерфейс для бизнес-контрактов или целей IoC, здесь я использую шаблон Singleton без статического класса

Синглтон обеспечивает способ поддержания состояния в сценариях без сохранения состояния

Надеюсь, это поможет вам ..

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