Избегание доступа к статическому члену типа через производный тип

Я считаю, что это чисто предупреждение Resharper, но причина этого (объясненная здесь) имеет смысл. Что говорит Грег Бич, так это то, что вы можете вызвать статический метод базового класса из родственного класса... в свой пример он использует:

var request = (FtpWebRequest)HttpWebRequest.Create(...)

... что вводит в заблуждение.

Так есть ли дизайн, который позволил бы мне избежать этого предупреждения в следующих классах?

public abstract class BaseLog {

    //  I omitted several other properties for clarity
    protected static string category;
    protected static TraceEventType severity;

    static BaseLog() {
        category = "General";
        severity = TraceEventType.Information;
    }

    public static void Write(string message) {
        Write(message, category, severity);
    }

    //  Writes to a log file... it's the same code for 
    //  every derived class.  Only the category and severity will change
    protected static void Write(string message, string messageCategory, TraceEventType messageSeverity) {

        LogEntry logEntry = new LogEntry(message, messageCategory, messageSeverity);

        //  This is Microsoft's static class for logging... I'm wrapping it to 
        //  simplify how it's called, but the basic principle is the same:
        //  A static class to log messages
        Logger.Write(logEntry);

    }

}


public class ErrorLog : BaseLog {

    static ErrorLog() {
        category = "Errors";
        severity = TraceEventType.Error;
    }

    //  I can add more functionality to the derived classes, but
    //  the basic logging functionality in the base doesn't change
    public static void Write(Exception exc) {
        Write(exc.Message);
    }

}


//  Code that could call this...
catch (Exception exc) {
    //  This line gives me the warning
    ErrorLog.Write("You did something bad");
    ErrorLog.Write(exc);
}

Один ErrorLog обслуживает приложение, и его настройки никогда не меняются (есть также TraceLog и ThreadLog). Я не хочу дублировать код ведения журнала, потому что он одинаков для каждого производного класса... сохранение его в BaseLog работает отлично. Итак, как мне спроектировать это, чтобы не нарушать этот принцип дизайна?

Классы статичны, потому что я не хочу создавать экземпляр нового объекта ErrorLog каждый раз, когда я хочу что-то записать в журнал, и я не хочу, чтобы 50 из них плавали в форме переменной уровня члена в каждом классе, который я пишу. Для ведения журнала используется корпоративная библиотека Microsoft, если это имеет значение.

ТИА!
Джеймс


person James King    schedule 10.12.2010    source источник


Ответы (1)


Кажется, что вы хотите держать дверь открытой для расширения, но не для модификации, также известной как принцип «открыто-закрыто». И это достойная цель.

Я бы посоветовал убрать статику и превратить классы-держатели функций в объекты. Это позволяет вам переопределять (и не путать других читателей) по мере необходимости — полиморфизм работает только с экземплярами.

Следующей проблемой будет необходимость иметь глобальный объект вместо передачи экземпляра регистратора. Создайте другой тип, предоставляющий доступ к одному экземпляру объекта регистратора. (старый синглтон)

e.g. ErrorLogProvider.Instance.Write(something)

PS: Халява - проще эти объекты тоже тестировать.

person Gishu    schedule 10.12.2010
comment
Интересный подход... сегодня вечером обдумаю это. Итак, если я правильно понимаю вас, ErrorLogProvider будет статическим классом со статической переменной-членом типа ErrorLog, экземпляр которой будет создан в статическом конструкторе провайдера и представлен через свойство Instance - person James King; 10.12.2010
comment
@ Джеймс - Да. Ответственность ErrorLogProvider за предоставление доступа к (кэшированному?) объекту регистратора. Возвращаемый тип этого метода может быть базовым типом, что позволяет клиентам не заботиться о точном типе регистратора. ErrorLogProvider может настроить правильный тип регистратора на основе файла конфигурации/DI/явного метода инициализации... - person Gishu; 10.12.2010