2017-09-10 4 views
-2

저는 프로젝트에서 두 개의 싱글 톤 클래스를가집니다.싱글 톤 팩토리가 복수 싱글 톤 인스턴스를 생성합니다.

public class VStateManager : IVState 
{ 
    private static readonly object _createLock = new object(); 
    private static VStateManager _vsManager = null; 
    public static VStateManager GetVStateManager() 
    { 
     lock (_createLock) 
     { 
      if (_vsManager == null) 
      { 
       return new VStateManager(); 
      } 
      return _vsManager; 
     } 
    } 
} 

public class VTRFactory : IVTR 
{ 
    private static VehicleFactory _VTRFactory =null; 
    private static readonly object _createLock = new object(); 

    public static VehicleFactory GetVTRFactory() 
    { 
     lock(_createLock) 
     { 
      if(_VTRFactory == null) 
      { 
       return new VTRFactory(); 
      } 
      return _VTRFactory; 
     } 
    } 
} 

내 동료가 일반적인 인터페이스를 받아 생산하는 싱글 톤 클래스 (something like a singleton factory)을 만들 제안 모두 singleton objects

방법이 작업을 수행 할 수 있습니다 이.?

답변

2

우선, 클래스가 싱글 톤을 전혀 구현하지 않습니다. 이것 좀 봐 :

if (_vsManager == null) 
{ 
    return new VStateManager(); 
} 
return _vsManager; 

_vsManager는 항상 null, 여러 인스턴스는 인스턴스에 액세스 할 때마다 생성 될 것입니다. 그것은해야한다 :

당신은 단지 하나의 인스턴스를 확인하는 방식이 생성 될 것
if (_vsManager == null) 
{ 
    _vsManager = new VStateManager(); 
} 
return _vsManager; 

.

또한, 나는 속성 대신 기능을 사용, 그것은 더 명확 :

public class VStateManager : IVState 
{ 
    private static readonly object _createLock = new object(); 
    private static VStateManager _vsManager = null; 
    public static VStateManager Instance 
    { 
     get 
     { 
      lock (_createLock) 
      { 
       if (_vsManager == null) 
       { 
        _vsManager = new VStateManager(); 
       } 
       return _vsManager; 
      } 
     } 
    } 
} 

이 그럼 당신은 예를 VStateManager.Instance.XXX에 따라 사용할 수 있습니다.

둘째, 왜 이러한 싱글 톤을 만들려면 세 번째 클래스가 필요합니까? GetXXXX에 액세스 할 필요가있을 때 필요한 인스턴스를 만들면 필요하기 전에 인스턴스를 만들 이유가 있습니까? 당신이 정말로 그들이 다음과 같이 매우 간단 뭔가 할 수있는 필요하기 전에 해당 인스턴스를 초기화 할 필요가있는 경우

: 초기화하는 그런

public static class Initializer() 
{ 
    public static void Init() 
    { 
     var a = VStateManager.GetVStateManager(); 
     var b = VehicleFactory.GetVTRFactory(); 
    } 
} 

그냥 Initializer.Init()를 호출합니다. 아무 이유없이 코드를 과도하게 복잡하게 만드는 것은 프로그래밍의 모든 악의 근원이며, 솔루션이 실제 문제를 야기 할 수 있기 때문에 존재하지 않는 문제를 해결하려고 시도하지 마십시오.

1

찾고있는 싱글 톤 팩토리는 제네릭을 사용하여 만들 수 있습니다. 싱글 톤 인스턴스를 생성해야하는 유형을 전달해야하며 팩토리는 해당 유형의 인스턴스가 하나만 생성되도록 해당 유형의 인스턴스를 리턴합니다.

이러한 싱글 톤 팩토리의 가장 기본적인 구현은 다음과 같이 보입니다.

public static class SingletonFactory 
{ 
    private static readonly object lockObject = new object(); 
    //Dictionary to store the singleton objects 
    private static readonly Dictionary<string, object> singletonObjects = new Dictionary<string, object>(); 

    // Method to retrieve singleton instance. 
    // Note the constraint "new()". This indicates that this method can be called for the types which has default constructor. 
    public static T GetSingletoneInstance<T>() where T:new() 
    { 
     var typeName = typeof(T).Name; 
     T instance; 

     lock (lockObject) 
     { 
      // Check in the dictionary if the instance already exist. 
      if (singletonObjects.ContainsKey(typeName)) 
      { 
       //Retrieve the instance from the dictionary. 
       instance = (T) singletonObjects[typeName]; 
      } 
      else 
      { 
       // If it does not exist in the dictionary, 
       // create a new instance 
       // and store it in the dictionary. 
       lock (lockObject) 
       { 
        instance = new T(); 

        singletonObjects.Add(typeName, instance); 
       } 
      } 
     } 

     // Return the instance of type "T" either retrieved from dictionary 
     // or the newly created one. 
     return instance; 
    } 
} 

다음은이 팩토리 사용 방법입니다.

class Program 
{ 

static void Main(string[] args) 
    { 
     var vstateManager = SingletonFactory.GetSingletoneInstance<VStateManager>(); 

     var vehicleFactory = SingletonFactory.GetSingletoneInstance<VehicleFactory>(); 

     Console.ReadKey(); 
    } 
} 

SingletonFactory의 구현은 아주 기본적인 버전입니다. 또한 기본 생성자가있는 유형에만 사용할 수 있다는 제한이 있습니다.

그러나 DI 모듈을 사용하여 생성자에 대한 걱정없이 인스턴스를 초기화 할 수 있습니다. 또한 인스턴스를 다른 곳에 저장하고 캐시, memcaches 또는 데이터베이스와 같은 사전을 확장 할 수 있습니다.

이 정보가 도움이 되었기를 바랍니다.