2013-03-25 2 views
0

Я много читал в экземпляре по сравнению с статическими классами и не нашел ответа на свой вопрос. Существуют ли какие-либо опасности для создания другого класса в статическом классе, на который ссылался класс экземпляра?экземпляр класса-> статический класс-> класс экземпляра в C#

Текущий проект, с которым я работаю, - это тот, в котором классы экземпляров называют статический метод «Логгер» (передача ряда параметров) для регистрации ошибок в текстовом файле в файловой системе. Я рефакторинг статического метода «Логгер» для создания экземпляра класса параметров (который представляет собой всего лишь ряд свойств и несколько вспомогательных методов для возврата себя как XML или строки) и класса DBLogger для регистрации ошибки в базе данных, а не файловой системы, передав класс параметра в качестве единственного параметра.

Эта модель хорошо работала в моем устаревшем коде VB6, в котором класс Logger был инстансом, а не статичным.

Но теперь в коде .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') в качестве поля, а не строки, - пусть вызывающий формат отформатирует его, если захочет, и как они хотят. Я бы также использовал 'UtcNow' вместо' Now' - всегда входить в UTC, так что неважно, где в мире работает код. –

0

Для этого я бы использовал комбинацию поставщика и одноэлементного шаблона.

Создайте абстрактный класс под названием Logger.

  1. Класс Logger содержит абстрактные методы для записи в журнал. Например:
    • abstract void LogInfo (информация LogInfo);
    • abstract void LogError (исключение исключения);
    • и т.д.
  2. Класс Logger содержит закрытый экземпляр объекта Logger.
  3. Класс Logger содержит статическое свойство, возвращающее частный экземпляр.
  4. Класс Logger содержит статический конструктор, который создает экземпляр частного экземпляра объекта Logger. Вы, вероятно, используете Reflection и создаете экземпляр объекта на основе конфигурации.
  5. Реализовать FileLogger, который наследуется от объекта Logger. Этот регистратор записывает в файл.
  6. Реализовать SQLLogger, который наследует объект Logger. Этот регистратор записывает в базу данных.

Зов регистратор так:

  • Logger.Instance.WriteInfo (информация);
  • Logger.Instance.WriteError (исключение);

Есть несколько преимуществ использования этой конструкции:

  1. Ваша функциональность каротаж полностью абстрагируется. Это полностью отделяет вызывающих абонентов от кода, который записывает журналы. Это позволяет записывать журнал в любые хранилища данных.
  2. Вы можете изменить, какой регистратор использовать без компиляции кода. Просто обновите файл конфигурации.
  3. Singleton гарантирует безопасность нитей
  4. Испытание. Вы можете писать тесты Mock против абстрактных классов.

Надеюсь, это поможет.

+0

Спасибо, это хорошая альтернатива. – user2208719

0

Нет проблем с параллелизмом со статическими методами.

Статические переменные - это другое дело.