Дизайн класса:Обертывание файла данных в класс с точки зрения потокобезопасности и тестируемости.

StackOverflow https://stackoverflow.com/questions/208184

Вопрос

Я пишу приложение на C# (.net 3.5), и у меня есть вопрос о дизайне классов:

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

Как мне это спроектировать с точки зрения потокобезопасности и возможности модульного тестирования (для модульных тестов необходимо использовать другие входные файлы, чем в рабочем коде)?Любая помощь очень ценится.

Это было полезно?

Решение

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

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

Для модульного тестирования вашего класса я бы посоветовал, если возможно, работать с общим потоком, а не просто с файлом.Затем вы можете вставлять различные тестовые файлы в свою тестовую сборку и обращаться к ним с помощью GetManifestResourceStream.В прошлом я делал это несколько раз, с большим успехом.

Другие советы

Использовать ЧитательПисательБлокировка, что, я думаю, соответствует описанию проблемы.

Ниже приводится быстрая и грязная реализация.Приобретение блокировок могло бы быть более разумным, например, несколько попыток перед спасением и т. д.Но вы поняли суть:

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);
     }
   }
}

Что касается потокобезопасности:Безопасность потоков не является проблемой, если только несколько потоков в рамках одного приложения будет одновременно ссылаться на один и тот же экземпляр вашего класса.Если ваш класс не содержится на сервере вне процесса, несколько приложений не смогут одновременно обращаться к одному и тому же экземпляру.Таким образом, конфликты, которые вы, скорее всего, увидите, будут связаны с нарушениями совместного использования файлов, а не с проблемами потоков (другими словами, разные случаи класса, пытающегося читать и писать одно и то же файл).И да, вы должны разработать свой код для правильной работы с общим доступом к файлам.

Один из способов сделать модуль класса доступным для тестирования — предоставить классу поток в конструкторе, а не напрямую обращаться к файлу.Тогда модульный тест может предоставить, например, поток памяти вместо потока файлов.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top