2008-10-16 3 views
0
내가 C의 # (.NET 3.5)에서 응용 프로그램을 쓰고 있어요

에 대한 클래스에 데이터 파일을 포장 및 I 클래스 디자인에 대한 질문이 있습니다클래스 디자인 : 스레드 안전성 및 테스트 용이성

내가 좋겠를 파일에 접근 (읽기, 쓰기)하고 그 내용을 클래스의 사용자 (instanciators)에게 제공하는 클래스를 생성하는 것을 좋아한다. 인스턴스에서 가장 일반적인 작업은 파일에서 특정 값을 검색하는 것입니다. 실제 읽기 및 쓰기 (io) 작업은 비싸지 만 파일 데이터를 메모리에 유지하고 모든 인스턴스가이 데이터에 액세스 할 수있게하려고합니다. 이 클래스는 다양한 응용 프로그램에서 동시에 사용되는 어셈블리에 있으므로 스레드 안전성에 대해 걱정해야합니다.

스레드 안전성 및 단위 테스트 가능성 (단위 테스트의 경우 조작 코드와 다른 입력 파일을 사용해야 함)과 관련하여 어떻게 설계합니까? 어떤 도움이라도 대단히 감사합니다.

답변

1

먼저 클래스를 적절한 인터페이스로 구현하십시오. 그렇게하면 클라이언트는 실제 파일이 필요없이 행동을 테스트 할 수 있습니다.

스레드 안전성을 테스트하는 것은 어렵습니다. 도구가 없다는 것은 아니지만, 그 앞에 정말 유용한 것을 본 적이 없습니다.

클래스 테스트의 경우, 가능한 경우 파일이 아닌 일반 스트림에서 작동해야한다고 제안합니다. 그런 다음 다른 테스트 파일을 테스트 어셈블리에 포함하고 GetManifestResourceStream을 사용하여 참조 할 수 있습니다. 저는 과거에 여러 번이 작업을 해 봤습니다. 큰 성공을 거두었습니다.

+0

좀 더 자세한 정보를 제공해 주시겠습니까? 나는 아직도 수업을 어떻게 디자인해야할지 모른다. 인터페이스는 어떻게 생겼을 까? GetFilePortionX/SetFilePortionY? 각 instaation과 함께 filedata를 다시로드하지 않으려면 어떻게해야합니까? 나와 함께 곰, 나는 초보자이고 정말로 이것에 붙어 있습니다. – Mats

+0

아, 나는 당신이 읽기 및 쓰기 권한이 필요하다는 것을 알지 못했습니다. 테스트 측면에서는 고통 스럽습니다.하지만 MemoryStream을 사용하여 테스트를 수행 할 수는 있습니다. 인터페이스에 관해서는 클라이언트가 필요로하는 것을 해결하십시오. Get/SetPortion은 모두 제공됩니까? 그렇다면 귀하의 인터페이스입니다. –

0

스레드 안전성에 대해 : 단일 응용 프로그램 내 복수 스레드 이 클래스의 동일한 인스턴스를 동시에 참조하지 않는 한 스레드 안전성은 문제가되지 않습니다. 클래스가 프로세스 외부 서버에 포함되어 있지 않으면 여러 응용 프로그램이 동일한 인스턴스를 동시에 참조 할 수있는 방법이 없습니다. 따라서 볼 수있는 충돌은 스레딩 문제가 아닌 파일 공유 위반에서 비롯됩니다. 즉, 다른 인스턴스의 클래스에서 동일한 파일을 읽고 쓰려고 시도합니다. 그리고 네, 파일 공유를 적절히 다루기 위해 코드를 설계해야합니다.

클래스 단위를 테스트 할 수있게 만드는 한 가지 방법은 클래스가 파일에 직접 액세스하지 않고 생성자에 스트림을 제공하는 것입니다. 그런 다음 단위 테스트는 파일 스트림을 제공하는 대신 메모리 스트림을 제공 할 수 있습니다.

+0

광고 thread-safety : 클래스를 정적으로 만들었더라도 다양한 응용 프로그램에서 동일한 정적 객체를 얻지 못합니다. ad testability : 귀하의 접근 방법에 대해 생각해 보았지만 피해야 할 인스턴스가 생성 될 때마다 파일에서 데이터를 읽어야합니다. – Mats

+0

별도의 AppDomains (또는 응용 프로그램)는 결코 인스턴스를 공유하지 않습니다. 인스턴스를 공유하는 유일한 방법은 독립 프로세스 서버를 사용하는 것입니다. –

1

을 사용하십시오. 문제 설명에 맞는 것 같습니다.

다음은 신속하고 더러운 구현입니다. 구금 등을하기 전에 여러 번 시도하는 것과 같이 자물쇠를 획득하는 것이 더 스마트해질 수 있습니다. 그러나 포인트를 얻으실 수 있습니다 :

public class MyFooBarClass 
{ 
    private static ReaderWriterLock readerWriterLock = new ReaderWriterLock(); 
    private static MemoryStream fileMemoryStream; 

    // other instance members here 

    public void MyFooBarClass() 
    { 
    if(fileMemoryStream != null) 
    { 
     // probably expensive file read here 
    } 

    // initialize instance members here 
    } 

    public byte[] ReadBytes() 
    { 
    try 
    { 
     try 
     { 
      readerWriterLock.AcquireReaderLock(1000); 
      //... read bytes here 
      return bytesRead; 
     } 
     finally 
     { 
      readerWriterLock.ReleaseReaderLock(); 
     } 
    } 
    catch(System.ApplicationException ex) 
    { 
     System.Diagnostics.Debug.WriteLine(ex.Message); 
    } 
    } 

    public void WriteBytes(bytes[] bytesToWrite) 
    { 
    try 
    { 
     try 
     { 
      readerWriterLock.AcquireWriterLock(1000); 
      //... write bytes here 
     } 
     finally 
     { 
      readerWriterLock.ReleaseWriterLock(); 
     } 
    } 
    catch(System.ApplicationException ex) 
    { 
     System.Diagnostics.Debug.WriteLine(ex.Message); 
    } 
    } 
}