ООП-пуристский вопрос
Jul. 26th, 2009 06:30 am![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Может ли класс, являющийся моделью для данных предметной области, содержать в себе ссылку на логгер(log4net,log4j) и выводить данные в лог? :)
Вот представьте себе, есть у вас описание какой-нибудь хреновины, например карточка клиента. И эта карточка при попытках сделать с ней что-нибудь нехорошее, записывает это дело и отсылает "куда нужно" :)
Если бы это был Haskell, такого вопроса не возникло бы вообще, т.к. данные они и есть данные, а в лог без таскания за собой IO или unsafePerformIO и не запишешь ничего.
Вот представьте себе, есть у вас описание какой-нибудь хреновины, например карточка клиента. И эта карточка при попытках сделать с ней что-нибудь нехорошее, записывает это дело и отсылает "куда нужно" :)
Если бы это был Haskell, такого вопроса не возникло бы вообще, т.к. данные они и есть данные, а в лог без таскания за собой IO или unsafePerformIO и не запишешь ничего.
no subject
Date: 2009-07-26 03:49 am (UTC)no subject
Date: 2009-07-26 03:52 am (UTC)no subject
Date: 2009-07-26 03:56 am (UTC)Если это библиотека, то было бы неплохо использовать шаблон функциональности, параметризованный трассировочным классом (функцией?), соответствующей какому-то условному стандарту, и описать этот стандарт концептом (если бы он был зааппрувлен). Если это не C++ (по виду — Java), то тогда не очень знаю, как там такое замутить. Наверное при инстанциации класса передавать логгер, с известным интерфейсом, в параметре.
no subject
Date: 2009-07-26 04:01 am (UTC)Но у меня конкретно, в дотнете, это вообще статик поле, как принято их инициализировать:
static log4net.ILog mLog = log4net.LogManager.GetLogger(System.Reflection.MethodInfo.GetCurrentMethod().DeclaringType);
no subject
Date: 2009-07-26 04:05 am (UTC)no subject
Date: 2009-07-26 04:07 am (UTC)no subject
Date: 2009-07-26 06:43 am (UTC)Можно, конечно, сделать логирование заюзав AOP, но как-то не прижилась эта идея в продакшене.
no subject
Date: 2009-07-26 04:00 am (UTC)Для целей тестирования, как минимум, важно иметь возможность извлечь функциональность и потыкать её с разных сторон. Логгинг этому будет мешать в какой-то степени, но остальные взаимодействия с внешним миром как пить дать мешать этому будут гораздо больше. Например, чтение конфига, отдача ответов по SNMP, etc — это всё пристёгиваемые сверху (методом взятия на себя ответственности за ведение обсуждаемой функциональности) или сбоку (методом [опциональной] параметризации функциональности объектами со стандартным интерфейсом) активности.
Тогда можно добыть голый функционал и даже отдать его кому-то без исходников.
no subject
Date: 2009-07-27 09:11 am (UTC)no subject
Date: 2009-07-26 09:28 am (UTC)1) Синглтон
2) Ссылка на логгер
Дальше начинаются вопросы "как это всё оформить красиво". Т.е. дизайн.
Есть подозрение, что ты не описал задачу, которую решаешь.
Что тебя смущает?
no subject
Date: 2009-07-26 09:32 am (UTC)А вопрос заключается в том, что:
1) Меня напрягает "активное" поведение объекта данных. Это все равно, как бумага на столе после рисования на ней уползала со стола в копир и там себя копировала.
2) Ссылка из этого объекта во внешний мир. Не хаскелеобразно и бесит.
3) Я представляю себе, сколько всяких контекстов пришлось бы передавать моим объектам, будь они функционально чистыми, и мне становится страшно за будущее функциональной парадигмы.
no subject
Date: 2009-07-26 09:39 am (UTC)1) Разделение обязанностей.
Пусть у нас есть логирование карточки, запись в БД, etc.
Что декларирует ООПшный подход? Агрегирование ссылок на логгер иди БД-шный аксесор, вызов к ним.
Попробуем сделать по ФП-шному построим родственные классу функции "запись в лог", "запись в БД".
Таким образом, эти обязанности реализуются в функциях.
2) Комбинирование поведение.
Гамма завещал нам декоратор. Именно декоратором и являются построенные нами родственные функции.
Что остаётся? Ну, построить сущность (подозрительно напоминающую моноид) являющуюся по сути "классом" твоей карточки.
Дальше ты таскаешь карточки (суть данные) + сборную солянку (классы) и получаешь profit.
no subject
Date: 2009-07-26 09:47 am (UTC)no subject
Date: 2009-07-26 09:48 am (UTC)Функциональная парадигма всё-таки разделяет данные и поведение.
Потому нужно сосредоточиться на описании "классов" - т.е. поведения, а данные просто plain - болтаются сбоку.
Инкапсуляция достигается суть замыканием состояния в обработчике....
Всё верно ведь?
no subject
Date: 2009-07-26 09:54 am (UTC)no subject
Date: 2009-07-26 09:54 am (UTC)no subject
Date: 2009-07-26 02:46 pm (UTC)no subject
Date: 2009-07-26 06:28 pm (UTC)Единственное что можно поправить - это сильно сложное описание статического поля для экземпляра логгера. Если представить, что кому-то в руки попал твой класс, а логгер он ещё не скачал, то придётся не только создавать заглушку на ILog, но и приделывать таинственный неймпспейс log4net.
К тому же неясно, зачем тут рефлекшн. Точнее ясно, но неясно как логгер оторвать от класса с наличием этого рефлекшена.