0

我已经阅读了大量关于实例与静态类的内容,但还没有找到我的问题的答案。在实例类引用的静态类中实例化不同的类有什么危险吗?

我正在使用的当前设计是实例类调用静态“记录器”方法(传递一系列参数)以将错误记录到文件系统中的文本文件的设计。我正在重构静态“Logger”方法来实例化一个参数类(这只是一系列属性和一些帮助方法以将自身作为 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);
        }
    }

}
4

3 回答 3

3

不,这绝对没问题 - 如果您在方法中创建任何类的实例,那么声明该方法的类是否是静态类都没有关系。

此外,除非你有一些“特殊”的东西(例如,一个统计创建的实例数量的静态变量),否则在创建对象时遇到并发问题的可能性比使用现有对象时要小。基本上,几乎所有并发的棘手部分是找出可变数据在哪里共享 -听起来你在这里没有任何东西(尽管示例代码有助于澄清这一点)。

于 2013-03-25T18:48:19.013 回答
0

静态方法没有并发问题。

静态变量是另一回事。

于 2013-10-03T01:40:37.070 回答
0

我会为此使用提供者和单例模式的组合。

创建一个名为 Logger 的抽象类。

  1. Logger 类包含用于写入日志的抽象方法。例如:
    • 抽象无效LogInfo(LogInfo信息);
    • 抽象无效LogError(异常异常);
    • ETC
  2. Logger 类包含 Logger 对象的私有实例。
  3. Logger 类包含一个返回私有实例的静态属性。
  4. Logger 类包含一个静态构造函数,用于实例化 Logger 对象的私有实例。您可能会使用反射并根据配置实例化对象。
  5. 实现一个继承自 Logger 对象的 FileLogger。此记录器写入文件。
  6. 实现一个继承自 Logger 对象的 SQLLogger。此记录器写入数据库。

像这样调用记录器:

  • Logger.Instance.WriteInfo(info);
  • Logger.Instance.WriteError(异常);

使用这种设计有几个优点:

  1. 您的日志记录功能是完全抽象的。这将日志调用者与写入日志的代码完全分离。这允许您将日志写入任何数据存储。
  2. 您可以在不编译代码的情况下更改要使用的记录器。只需更新配置文件。
  3. 单例保证线程安全
  4. 可测试性。您可以针对抽象类编写 Mock 测试。

希望这可以帮助。

于 2013-03-25T19:38:31.820 回答