По моему мнению, вы не должны ожидать слишком многого от 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
гарантируется только в скомпилированном коде компилятором. Во время выполнения процессор все еще может переупорядочивать данные и назначение команд в соответствии с архитектурой процессора. Оборудование может получить неверные данные (предположим, гаджет сопоставлен с аппаратным вводом / выводом). Необходим барьер памяти между данными и назначением команд.
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:
In that case I would have the following interfaces or APIs, which might deserve logging:
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:
Регистрация и отслеживание должны быть сквозными проблемами. Вы можете добавить / удалить их в любое время декларативным способом, если вы используете аспектно-ориентированное программирование.
Мы TDD, поэтому мы больше не ведем много журналов. Может быть, только в обработчиках исключений верхнего уровня и в нескольких стратегических местах.
Я бы не сказал, что "Получение тортов из репозитория" лучше всего подходит ИНФО. Это больше подходит для DEBUG или даже TRACE. Обычно вы хотите использовать INFO для регистрации функциональных вещей, например, «Для пользователя A не осталось тортов». ИМХО нефункциональный хлам и техническая подача должны быть с меньшей степенью серьезности. Я бы не стал использовать FATAL для регистрации исключений, если вы не дойдете до точки, когда приложение полностью мертво ... было бы довольно запутанно увидеть FATAL, а затем система все еще жива и работает. ОШИБКА - лучший выбор, иногда даже ПРЕДУПРЕЖДЕНИЕ, зависит от того, насколько серьезным является исключение. Что касается перехватчиков АОП, то в прошлый раз я проверял - они сильно влияют на производительность. Это круто и сексуально, но в моем случае было непрактично, не уверен, что дальше демонстраций и тривиальных примеров из книг и статей, объясняющих преимущества АОП, можно. Так что я бы дважды проверил, прежде чем полностью полагаться на это.