2013-03-25 6 views
0

정적 클래스와 정적 클래스에서 많은 내용을 읽었으며 내 질문에 대한 답을 찾지 못했습니다. 인스턴스 클래스에 의해 참조 된 정적 클래스에 다른 클래스를 인스턴스화하는 데 어떤 위험이 있습니까?C#의 인스턴스 클래스 -> 정적 클래스 -> 인스턴스 클래스

현재 작업중인 클래스는 인스턴스 클래스가 파일 시스템의 텍스트 파일에 오류를 기록하기 위해 일련의 매개 변수를 전달하는 정적 "로거"메서드를 호출하는 디자인입니다. 나는 정적 인 "Logger"메소드를 리팩터링하여 매개 변수 클래스 (일련의 속성 및 XML 또는 문자열 자체를 반환하는 몇 가지 도우미 메소드)와 DBLogger 클래스를 인스턴스화하여 데이터베이스에 오류를 기록하지 않고 파일 시스템에서 매개 변수 클래스를 유일한 매개 변수로 전달합니다.

이 모델은 정적이 아닌 Logger 클래스가 인스턴스화 된 내 기존 VB6 코드에서 잘 작동합니다.

하지만 이제 .NET 코드에서 정적 인 2 개의 새로운 클래스 (매개 변수 및 DBLogger)를 만들어야하는지 또는 DBLogger를 정적으로 설정하고 인스턴스를 매개 변수 클래스로 설정해야하는지 확실하지 않습니다. 나는 동시성/다중 스레드 데이터 문제에 대한 가능성에 대해 우려하고있다 (또는없는) 정적 클래스에서 생성되는 인스턴스. 걱정할 권리가 있습니까? 아니면 아무것도 걱정하지 않습니까?

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.IO; 

// all code truncated for illustration purposes 

namespace ThisIs.A.Test 
{ 
    //INSTANCE 
    public class ErrorLogParameters 
    { 
     private int mThreadId = 0; 
     private int mErrorNumber = 0; 
     private string mServerDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"); 

     public int ThreadId 
     { 
      get { return mThreadId; } 
      set { mThreadId = value; } 
     } 
     public int ErrorNumber 
     { 
      get { return mErrorNumber; } 
      set { mErrorNumber = value; } 
     } 
     public string ServerDate 
     { 
      get { return mServerDate; } 
     } 
    } 

    //INSTANCE 
    public class ErrorLog 
    { 
     public void LogErrorToDatabase(ErrorLogParameters criteria) 
     { 
      //Log error to database here 
     } 
    } 

    //STATIC - Instantiates INSTANCE of ErrorLogParameters and ErrorLog 
    public class Logger 
    { 
     public static void WriteLog(string pstrObjectName, string pstrProcedureName, int plngErrNumber, string pstrErrDescription) 
     { 
      // create a new parameter object 
      ErrorLogParameters objParameters = new ErrorLogParameters(); 

      // populate object properties 
      objParameters.ErrorNumber = mlngErrNumber; 
      objParameters.ThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId; 

      ErrorLog objErrorLog = new ErrorLog(); 

      objErrorLog.LogErrorToDatabase(objParameters); 
     } 
    } 

    //INSTANCE - Invokes STATIC method 
    public class SomeInstance 
    { 
     private void ErrorHandler_Log(Exception exception, string procedureName, string additonalDescription, string stackTrace) 
     { 
      // call from instance class to static class 
      Logger.WriteLog(mstrObjectName, procedureName, mlngErrNumber, mstrErrDescription); 
     } 
    } 

} 
+0

당신은 싱글 톤 패턴에 대해 이야기하고 있습니까? 로거는 싱글 톤으로 구현되는 경우가 많으므로 실제로 많은 문제가 발생할 것이라고 생각하지는 않습니다. 나는이 자식 인스턴스를 가진 로거의 정적 개념이 많은 의미를 갖게한다고 생각한다. –

+0

당신이 말하는 내용을 더 잘 이해할 수 있도록 코드를 추가하면 정말 도움이 될 것입니다. – konkked

답변

3

아니, 그 절대적으로 괜찮아요 - 당신이 방법 내에서 모든 클래스의 인스턴스를 생성하는 경우, 그 방법을 선언하는 클래스는 정적 클래스인지 여부는 중요하지 않습니다. 당신이 "특별한"무언가를 가지고하지 않는 한

또한, 기존 객체를 사용하면 새로운 객체를 생성 할 때보다 동시성 문제로 실행 가능성이 적다 (생성 된 인스턴스의 수를 계산 정적 변수 등)를 사용할 때 . 기본적으로, 거의 모든 동시성의 까다로운 부분은 변경 가능한 데이터가 공유되는 곳에서 작동합니다. 사운드과 같지 않습니다 (예제 코드가이를 명확히하는 데 도움이되지만).

+0

당신의 대답은 제가 찾고있는 대답이라고 생각합니다. 그러나 지금 제 코드 샘플을 추가했습니다. – user2208719

+0

@ user2208719 : 나는'ErrorLogParameters'를 변경하여'DateTime' (또는'DateTimeOffset')을 문자열이 아닌 필드로 유지할 것을 강력히 고려할 것입니다. 또한'Now' 대신'UtcNow'를 사용합니다 - 항상 UTC로 로그인하십시오. 그래서 코드가 실행되는 곳은 세계 어디에서도 상관 없습니다. –

0

나는 이것을 위해 제공자와 싱글 톤 패턴의 조합을 사용할 것이다.

Logger라는 추상 클래스를 만듭니다.

  1. Logger 클래스는 로그에 기록하기위한 추상 메소드를 포함합니다. 예 :
    • abstract void LogInfo (LogInfo info);
    • abstract void LogError (예외 예외);
  2. 로거 클래스는 로거 객체의 개인 인스턴스를 포함하고 있습니다.
  3. Logger 클래스에는 개인 인스턴스를 반환하는 정적 속성이 포함되어 있습니다.
  4. Logger 클래스에는 Logger 객체의 전용 인스턴스를 인스턴스화하는 정적 생성자가 포함되어 있습니다. 아마도 Reflection을 사용하고 구성에 따라 객체를 인스턴스화합니다.
  5. Logger 개체를 상속 한 FileLogger를 구현하십시오. 이 로거는 파일에 기록합니다.
  6. Logger 개체를 상속 한 SQLLogger를 구현하십시오. 이 로거는 데이터베이스에 기록합니다.

콜과 같이 로거 :

  • Logger.Instance.WriteInfo (정보);
  • Logger.Instance.WriteError (exception);

이 디자인을 사용하는 몇 가지 이점이 있습니다

  1. 로깅 기능을 완전히 추상화입니다. 이렇게하면 로깅 호출자가 로그를 작성하는 코드와 완전히 분리됩니다. 이렇게하면 모든 데이터 저장소에 로그를 쓸 수 있습니다.
  2. 코드를 컴파일하지 않고 사용할 로거를 변경할 수 있습니다. 설정 파일을 업데이트하십시오.
  3. 싱글 톤 보장 스레드 안전성
  4. 테스트 가능성. 추상 클래스에 대한 모의 테스트를 작성할 수 있습니다.

희망이 도움이됩니다.

+0

감사합니다. 좋은 대안입니다. – user2208719

0

정적 메서드에는 동시성 문제가 없습니다.

정적 변수는 다른 점입니다.

관련 문제