В каком этапе Вы добавляете вход и трассировку в OO?

По моему мнению, вы не должны ожидать слишком многого от volatile. Чтобы проиллюстрировать это, посмотрите на пример из высоко оцененного ответа Нильса Пипенбринка .

Я бы сказал, его пример не подходит для volatile. volatile используется только для: предотвращения компилятора от полезных и желательных оптимизаций . Это не относится к потокобезопасности, атомарному доступу или даже к порядку памяти.

В этом примере:

    void SendCommand (volatile MyHardwareGadget * gadget, int command, int data)
    {
      // wait while the gadget is busy:
      while (gadget->isbusy)
      {
        // do nothing here.
      }
      // set data first:
      gadget->data    = data;
      // writing the command starts the action:
      gadget->command = command;
    }

только gadget->data = data перед gadget->command = command гарантируется только в скомпилированном коде компилятором. Во время выполнения процессор все еще может переупорядочивать данные и назначение команд в соответствии с архитектурой процессора. Оборудование может получить неверные данные (предположим, гаджет сопоставлен с аппаратным вводом / выводом). Необходим барьер памяти между данными и назначением команд.

6
задан 28 June 2009 в 11:00
поделиться

4 ответа

My software is in layers, with a well-defined API between each layer. I tend to implement logging for those APIs from the begining, so that for any given transaction I can see how that results in an API call at each of the underlying layers: if there's a mistake, that will help to narrow it down to a specific layer. The logging will also help to reproduce a problem by showing a log of all the previous, normal activity which led up to the problem.

I also add assertions within each layer where I can, and log assertion failures.

A log file therefore often shows of a sequence of calls to the public APIs, with an error message generated from inside: that's often enough to diagnose the problem.

Beyond that, I add debug-level logging on an as-needed basis: to debug specific problems during development and/or after release.

My reasoning for caring about logging is partly explained in the following:

To fix any bug in released software, I depend on the log file; and the same is also often true of software as it's being developed.


You said,

I find I rarely decorate any lower level classes such as implementation of ICakeRepository with logger stuff as it seems pointless.

I said,

My software is in layers, with a well-defined API between each layer. I tend to implement logging for those APIs from the begining ...

I think I'd better explain what I mean by "layers", which may or may not be the same as your "lower level" classes.

For example, my system might have the following layers:

  • UI
  • Business layer (rules for manipulating data)
  • Data access layer (for database I/O)
  • Database

In that case I would have the following interfaces or APIs, which might deserve logging:

  • Between the user and the UI (i.e. the UI events, mouse and keyboard)
  • Between the UI and the business layer (see "Humble dialog box")
  • Between the business layer and the DAL
  • Between the DAL and the database

Alternatively the system might be a chain of components connecting two peer end-points (less obviously with "top" and "bottom" layers).

In any case, what I'm logging is the API that's each component's public facade, which is good for logging for several reasons:

  • Not too complicated (the facade tends to be simpler than the underlying/internal implementation)
  • Good coverage (if I log the whole facade, and if the only way into the component is via its facade, then I know I've logged everything that goes into the component)
  • Works well with Conway's Law: when debugging a system with multiple components, each developed by a different team, one of the recurrent questions is, "Which component is at fault, and therefore which team needs to debug it?"
2
ответ дан 17 December 2019 в 07:08
поделиться

Регистрация и отслеживание должны быть сквозными проблемами. Вы можете добавить / удалить их в любое время декларативным способом, если вы используете аспектно-ориентированное программирование.

1
ответ дан 17 December 2019 в 07:08
поделиться

Мы TDD, поэтому мы больше не ведем много журналов. Может быть, только в обработчиках исключений верхнего уровня и в нескольких стратегических местах.

1
ответ дан 17 December 2019 в 07:08
поделиться

Я бы не сказал, что "Получение тортов из репозитория" лучше всего подходит ИНФО. Это больше подходит для DEBUG или даже TRACE. Обычно вы хотите использовать INFO для регистрации функциональных вещей, например, «Для пользователя A не осталось тортов». ИМХО нефункциональный хлам и техническая подача должны быть с меньшей степенью серьезности. Я бы не стал использовать FATAL для регистрации исключений, если вы не дойдете до точки, когда приложение полностью мертво ... было бы довольно запутанно увидеть FATAL, а затем система все еще жива и работает. ОШИБКА - лучший выбор, иногда даже ПРЕДУПРЕЖДЕНИЕ, зависит от того, насколько серьезным является исключение. Что касается перехватчиков АОП, то в прошлый раз я проверял - они сильно влияют на производительность. Это круто и сексуально, но в моем случае было непрактично, не уверен, что дальше демонстраций и тривиальных примеров из книг и статей, объясняющих преимущества АОП, можно. Так что я бы дважды проверил, прежде чем полностью полагаться на это.

0
ответ дан 17 December 2019 в 07:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: