2013-08-28 2 views
2

Привет, Я заинтересован в реализации метода, который возвращает объект singleton. Я создал реализацию на основе примера, найденного в MSDN, но я не совсем уверен, что моя реализация является corect.Проверка реализации Singleton

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

Вот мой код:

public class FileShareAccessFactory : IFileShareAccessFactory 
{ 
    private volatile static IFileShareAccess m_fileShareAccess; 
    private static object m_SyncRoot = new object(); 

    public IFileShareAccess GetFileShareAccessInstance(IContextFactory contextFactory, ILogger logger) 
    { 
     if (m_fileShareAccess == null) 
     { 
      lock (m_SyncRoot) 
      { 
       if (m_fileShareAccess == null) 
       { 
        m_fileShareAccess = new FileShareAccess(contextFactory, logger); 
       } 
      } 
     } 
     return m_fileShareAccess; 
    } 
} 
+2

Пожалуйста, взгляните на правую панель вопроса –

+2

Напишите единичный тест. – Steven

+0

Что значит «как проверить, является ли это одним и тем же экземпляром объекта»? – Oscar

ответ

6

Как реализована реализация с двойной проверкой, да, это будет работать нормально. Ему даже не нужен volatile, так как синхронизированная двойная проверка будет иметь дело с любым небольшим количеством «это было ложным null». Лично я был бы больше обеспокоен тем фактом, что он , похоже, не уважает API - т.е. если я спрошу, если для экземпляра , указав конкретный контекст-фабрику и регистратор, он на самом деле дает мне что-то, что использовалось a не связанные контекстно-завод и регистратор. Честно говоря, есть также контейнеры IoC/DI, которые вы могли бы просто разгрузить.

+0

хорошее место относительно внешних зависимостей –

+0

Внешние зависимости всегда будут одинаковыми – aleczandru

0

Используйте object.ReferenceEquals(), чтобы проверить, если оба объекта и тот же экземпляр.

Например:

[TestMethod] 
    public void TestGetFileShareAccessInstance() 
    { 
     var first = FileShareAccessFactory.GetFileShareAccessInstance(contextFactory, logger); 
     var second = FileShareAccessFactory.GetFileShareAccessInstance(contextFactory, logger); 

     Assert.IsTrue(object.ReferenceEquals(first, second)); 
    } 
+0

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

+0

@MarcGravell, я согласен, что это всего лишь базовый ответ. –

0

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

Возможно, вам захочется взглянуть на инъекцию зависимостей, такую ​​как Unity. Таким образом, вы можете зарегистрировать этот класс с помощью ContainerControlledLifetimeManager, чтобы обеспечить синглтон как на фабрике контекста, так и на журнале. Это позволяет гибкость позже, когда у вас может быть больше фабрик контекста, поэтому необходимо больше FileShareAccessFactory s.

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

  1. Сделать конструктор приватным.
  2. Уплотнение класса - или может быть построен класс снизу.