Чи називаються так званими "наскрізними проблемами" вагомим приводом зламати SOLID / DI / IoC?


43

Мої колеги люблять говорити, що "ведення журналів / кешування / тощо. Є суперечливою проблемою", а потім продовжують використовувати відповідний сингл. І все ж вони люблять IoC та DI.

Це справді вагомий привід зламати принцип SOLI D ?


27
Я виявив, що принципи SOLID корисні здебільшого лише тим, хто вже має досвід, необхідний для несвідомого слідування їм.
svidgen

1
Я виявив, що термін "наскрізна проблема" є досить специфічним терміном (прив'язаним до аспектів) і не обов'язково бути синонімом сингтона. Ведення журналу може бути проблемою наскрізного значення в тому сенсі, що іноді ви хочете записати загальне повідомлення в декількох місцях однаковим чином (наприклад, журнал кожного виклику до способу обслуговування з тим, хто здійснив виклик або якийсь інший тип аудиту журналу). Однак я заперечую, що лісозаготівля (в загальному розумінні) не є наскрізною проблемою лише тому, що вона використовується скрізь. Я думаю, що це більше "всюдисуща проблема", хоча це насправді не стандартний термін.
Темп

4
@svidgen принципи SOLID також корисні, коли ті, хто їх не знає, переглядають ваш код і запитують вас, чому ви так зробили. Приємно бути в змозі вказати на принцип і сказати "ось чому"
candied_orange

1
Чи є у вас приклади, чому ви вважаєте, що ведення журналів - це особливий випадок? Це досить спрощений канал для переадресації деяких даних, зазвичай це частина будь-якої X-системи, яку ви використовуєте.
ksiimson

Відповіді:


42

Немає.

SOLID існує як керівництво для врахування неминучих змін. Ви дійсно ніколи не збираєтесь змінювати свою бібліотеку журналів, або ціль, або фільтрувати, або форматувати, або ...? Ви дійсно не збираєтесь змінювати бібліотеку кешування, або ціль, або стратегію, або масштабування, або ...?

Звичайно, ти є. За принаймні , ви будете хотіти , щоб знущатися ці речі в здоровому чином , щоб ізолювати їх для тестування. І якщо ви хочете ізолювати їх для тестування, ви, швидше за все, зіткнетеся з діловою причиною, де хочете ізолювати їх з реальних причин.

І ви тоді отримаєте аргумент про те , що реєстратор сам буде обробляти зміни. "О, якщо ціль / фільтрування / форматування / стратегія зміниться, ми просто змінимо конфігурацію!" Це сміття. Мало того, що тепер у вас є об'єкт God, який обробляє всі ці речі, ви пишете свій код у XML (або подібному), де не отримуєте статичного аналізу, не отримуєте помилок часу компіляції, і ви не ' t дійсно отримують ефективні одиничні тести.

Чи є випадки порушення інструкцій SOLID? Абсолютно. Іноді все не зміниться (не вимагаючи повного перезапису). Іноді незначне порушення ЛСП є найчистішим рішенням. Іноді створення ізольованого інтерфейсу не надає ніякої цінності.

Але реєстрація та кешування (та інші всюдисущі наскрізні проблеми) - це не такі випадки. Вони, як правило, прекрасні приклади стику та дизайну, які ви отримуєте, коли ігноруєте вказівки.


22
Яка альтернатива у вас тоді? Впорскуйте ILogger у кожен клас, який ви пишете? Написання декоратора для кожного класу, якому потрібен лісоруб?
Роберт Харві

16
Так. Якщо щось є залежністю, зробіть це залежністю . І якщо це означає занадто багато залежностей, або ви передаєте реєстратор кудись, це не повинно йти - добре , тепер ви можете виправити свою конструкцію.
Теластин


20
Справжнє питання, яке я маю з догматичним IoC, полягає в тому, що майже весь сучасний код залежить від чогось, що ні вводити, ні абстрагувати. Якщо ви пишете на C #, наприклад, ви не часто відбувається абстрагуватися Stringабо Int32навіть Listз вашого модуля. Там всього лише ступеня , в якій це розумно і розсудлива плану змін. І, за винятком найбільш очевидних "основних" типів, розпізнавання того, що ви, можливо, змінить , справді є лише питанням досвіду та судження.
svidgen

6
@svidgen - Сподіваюся, ви не прочитали моєї відповіді як пропагування догматичного ІОК. І тільки тому, що ми не абстрагуємося від цих основних типів (та інших речей, де розсудливі), це не означає, що добре мати глобальний список / рядок / Int / тощо.
Теластин

38

Так

У цьому і полягає вся суть терміна "наскрізний концерн" - це означає щось, що не вписується акуратно в принцип SOLID.

Тут ідеалізм зустрічається з реальністю.

Люди, які є напів новими в SOLID і наскрізних, часто стикаються з цим розумовим завданням. Це добре, не вигадуйте. Намагайтеся все ставити під термін SOLID, але є кілька місць, таких як реєстрація та кешування, де SOLID просто не має сенсу. Наскрізний брат - брат SOLID, вони йдуть рука об руку.


9
Обґрунтована, практична, не догматична відповідь.
user1936

11
Скажіть, будь ласка, чому всі п’ять принципів SOLID порушуються наскрізними проблемами? У мене є проблеми, щоб це зрозуміти.
Док Браун

4
Так. Я потенційно міг би придумати вагомий привід «порушити» кожен принцип окремо; але жодної причини зламати всі 5!
svidgen

1
Було б ідеально для мене, коли я не мав бити головою об стіну щоразу, коли мені потрібно знущатися з однотонного лісоруба / кеша для одиничного тесту. Уявіть, що було б, як тестувати веб-додаток, не маючи цього HttpContextBase(яке було введено саме з цієї причини). Я точно знаю, що моя реальність була б дуже кисла без цього класу.
devnull

2
@devnull, можливо, це вже тоді питання, а не пересічні проблеми ...
Борис Павук

25

Для лісозаготівлі я думаю, що це так. Ведення журналу є розповсюдженим та, як правило, не пов'язане з функціональністю сервісу. Загальноприйнято і добре зрозуміло використовувати рамки ведення журналів одиночних шаблонів. Якщо ви цього не зробите, ви створюєте та вставляєте реєстратори скрізь, і цього не хочете.

Одне з вищезазначених питань полягає в тому, що хтось скаже "але як я можу перевірити ведення журналу?" . Мої думки полягають у тому, що я зазвичай не перевіряю ведення журналу, але не заперечую, що я можу насправді читати файли журналів і розуміти їх. Коли я бачу тестування журналу, це зазвичай тому, що хтось повинен стверджувати, що клас насправді щось зробив, і вони використовують повідомлення журналу, щоб отримати такий зворотний зв'язок. Я набагато краще зареєструвати якогось слухача / спостерігача в цьому класі та запевнити в своїх тестах, що викликається. Потім можна помістити журнал подій всередині цього спостерігача.

Я думаю, кешування - це зовсім інший сценарій.


3
До цього часу я трохи поцікавився у FP, я почав проявляти великий інтерес до використання (можливо, монадійної) функції функції для вбудовування таких речей, як реєстрація, обробка помилок тощо у ваших випадках використання, не ставлячи жодного з них у основну логіку бізнесу ( див. fsharpforfunandprofit.com/rop )
сара

5
Ведення журналу не повинно бути поширеним. Якщо це так, то ви занадто сильно записуєтесь і ви просто створюєте для себе шум, коли вам потрібно переглядати ці журнали. Вводячи залежність реєстратора, ви змушені думати про те, чи потрібно насправді щось реєструвати.
RubberDuck

12
@RubberDuck - Скажіть мені, що "ведення журналу не повинно бути поширеним", коли я отримую звіт про помилку з поля, і єдина здатність налагодження, яку я маю зрозуміти, що сталося, - це той файл журналу, який я не хотів зробити загарбним. Урок, засвоєний, лісозаготівля повинна бути "всепоглинаючою", дуже розповсюдженою.
Данк

15
@RubberDuck: За допомогою серверного програмного забезпечення журнал - єдиний спосіб вижити. Це єдиний спосіб з'ясувати помилку, яка сталася 12 годин тому, а не зараз на власному ноутбуці. Не переживайте за шум. Використовуйте програмне забезпечення для управління журналом, щоб ви могли запитувати свій журнал (в ідеалі також слід налаштувати сигнали тривоги, які надсилатимуть вам електронні листи в журналах помилок)
slebetman

6
Наш співробітник служби підтримки зателефонував мені та скаже мені, що "клієнт натискав деякі сторінки та з’явилася помилка". Я запитую їх, що сказала помилка, вони не знають. Я запитую, що конкретно натиснув клієнт, вони не знають. Я запитую, чи можуть вони відтворюватись, вони не можуть. Я погоджуюсь, що реєстрація може бути досягнута в основному за допомогою добре розгорнутих реєстраторів в декількох ключових точках шарніру, але невеликі дивні повідомлення тут і є безцінними. Побоювання журналу призводить до зниження якості програмного забезпечення. Якщо у вас є занадто багато даних, підріжте назад. Не оптимізуйте передчасно.
Темп

12

Мої 2 копійки ...

Так і ні.

Ви ніколи не повинні дійсно порушувати принципи ви приймаєте; але ваші принципи завжди повинні бути впорядковані і прийняті на службу до вищої мети. Отже, при правильно обумовленому розумінні деякі видимі порушення можуть не бути фактичними порушеннями "духу" або "тіла принципів в цілому".

Зокрема, принципи SOLID, крім того, що вимагають багато нюансів, в кінцевому підсумку підпорядковуються меті "забезпечення робочого, ремонтованого програмного забезпечення". Отже, дотримання будь-якого конкретного принципу SOLID є самозакоханим та суперечливим, коли це робить, суперечить цілям SOLID. І тут, я часто відзначаю , що поставляючи козирі ремонтопридатність .

Отже, що з D у SOLID ? Ну, це сприяє підвищенню ремонтопридатності, роблячи модуль багаторазового використання відносно агностичним щодо його контексту. І ми можемо визначити "модуль багаторазового використання" як "колекцію коду, який ви плануєте використовувати в іншому окремому контексті". І це стосується єдиних функцій, класів, наборів класів та програм.

І так, зміни реалізацій реєстратора, ймовірно, ставлять ваш модуль у "інший чіткий контекст".

Отже, дозвольте запропонувати два мої великі застереження :

По-перше: малювання рядків навколо блоків коду, які складають "модуль багаторазового використання", - це питання професійного судження. І ваше судження обов'язково обмежується вашим досвідом.

Якщо ви не в даний час планують використовувати модуль в іншому контексті, це , ймовірно , добре для того , щоб безпорадно залежати від нього. Застереження про застереження: Ваші плани, ймовірно, неправильні - але це теж нормально. Чим довше ви пишете модуль за модулем, тим більше і інтуїтивніше і точніше будете відчувати, чи буде "мені знову це потрібно колись". Але, напевно, ви ніколи не зможете ретроспективно сказати: "Я модулював і деакупував все якомога більше, але без зайвого ".

Якщо ви відчуваєте вину за свої помилки в суді, перейдіть до визнання і продовжуйте ...

По-друге: інвертування керування не дорівнює залежності від введення .

Це особливо актуально, коли ви починаєте вводити залежності від нудоти . Ін'єкція залежності - корисна тактика для всеосяжної стратегії ІОК. Але я б заперечив, що DI має меншу ефективність, ніж деякі інші тактики - як, наприклад, використання інтерфейсів та адаптерів - поодинокі точки впливу контексту зсередини модуля.

І давайте дійсно зосередимося на цьому на секунду. Тому що, навіть якщо ви вводите Logger нудоту реклами , вам потрібно написати код проти Loggerінтерфейсу. Ви не можете почати використовувати новий Loggerвід іншого постачальника, який приймає параметри в іншому порядку. Ця здатність походить від кодування в модулі проти інтерфейсу, який існує всередині модуля і в якому є один підмодуль (Адаптер) для управління залежністю.

А якщо ви кодуєте адаптер, то Loggerвводиться чи адаптер у цей адаптер або виявляється адаптером, як правило, є малозначущим для загальної мети щодо ремонту. І що ще важливіше, якщо у вас є адаптер рівня модуля, то, мабуть, просто безглуздо вводити його в що-небудь. Це написано для модуля.

tl; dr - Перестаньте метушитися щодо принципів, не враховуючи, чому ви використовуєте принципи. І, більш практично, просто створити Adapterдля кожного модуля. Використовуйте судження, вирішуючи, де ви намалюєте межі "модуля". Зсередини кожного модуля йдіть далі та зверніться безпосередньо до Adapter. І обов'язково введіть справжній реєстратор у Adapter- але не в кожну дрібницю, яка може знадобитися.


4
Людина ... Я б сказав коротшу відповідь, але в мене не було часу.
svidgen

2
+1 за використання адаптера. Вам потрібно виділити залежності від сторонніх компонентів, щоб дозволити їх замінювати, де це можливо. Реєстрація журналу - це легка ціль для цього - багато реалізацій журналів існують і мають здебільшого подібні API, тому проста реалізація адаптера дозволяє вам змінити їх дуже легко. А людям, які кажуть, що ти ніколи не зміниш свого постачальника журналів: мені довелося це зробити, і це спричинило справжній біль, оскільки я не використовував адаптер.
Жуль

"Принципи SOLID, зокрема, крім того, що вимагають багато нюансів, в кінцевому рахунку підпорядковуються цілі" забезпечення робочого, ремонтованого програмного забезпечення "." - Це одне з найкращих тверджень, які я бачив. Як м'яко-OCD кодер, я мав свою частку боротьби з ідеалізмом проти продуктивності.
DVK

Кожен раз, коли я бачу +1 або коментар до старої відповіді, я читаю свою відповідь ще раз і знову виявляю, що я страшенно неорганізований і незрозумілий письменник ... Я дуже ціную коментар, @DVK.
svidgen

Адаптери - це економія життя, вони не коштують великих витрат і полегшують ваше життя, особливо коли ви хочете застосувати SOLID. Тестування - вітер з ними.
Алан

8

Ідея про те, що ведення журналу завжди має здійснюватися як одиночний, - одна з тих брехні, про які говорили так часто, що набрала тяги.

Поки про сучасні операційні системи було розпізнано, ви можете зайти в декілька місць залежно від характеру виводу .

Дизайнери систем повинні постійно ставити під сумнів ефективність попередніх рішень, перш ніж сліпо включати їх у нові. Якщо вони не проводять такої ретельності, то вони не виконують свою роботу.


2
Яке ваше запропоноване рішення тоді? Чи вводить ILogger у кожен клас, який ви пишете? Що з використанням візерунка «Декоратор»?
Роберт Харві

4
Насправді не відповідаючи на моє запитання, чи не так? Я вказав шаблони лише як приклади ... Це не повинно бути тими, якщо у вас є щось краще.
Роберт Харві

8
Я не дуже розумію цю відповідь з точки зору будь-яких конкретних пропозицій
Брайан Агнеу

3
@RobbieDee - Отже, ви говорите про те, що ведення журналів має здійснюватися найскладнішим і незручнішим способом через «випадковість», яку ми можемо захотіти ввійти в декілька місць? Навіть якщо подібні зміни відбулися, чи дійсно ви вважаєте, що додавання цього функціоналу до наявного екземпляра Logger буде більше роботи, ніж усіх зусиль для передачі цього Logger між класами та зміною інтерфейсів, коли ви вирішите, чи потрібно Logger чи ні десятки проектів, де ніколи не відбуватиметься реєстрація декількох місць?
Данк

2
Re: "Ви можете увійти в декілька місць залежно від характеру виводу": Безумовно, але найкращий спосіб обробляти це в рамках реєстрації , а не намагатися ввести кілька окремих залежностей журналу. (Загальні рамки ведення журналу вже підтримують це.)
ruakh

4

Справжній журнал - це особливий випадок.

@Telastyn пише:

Ви дійсно ніколи не збираєтесь змінювати свою бібліотеку журналів, або ціль, або фільтрувати, або форматувати, або ...?

Якщо ви передбачаєте, що вам може знадобитися змінити бібліотеку журналів, тоді вам слід використовувати фасад; тобто SLF4J, якщо ви перебуваєте в світі Java.

Що стосується решти, гідна бібліотека ведення журналів піклується про те, щоб змінити, куди йде журнал, які події фільтруються, як форматування подій журналу за допомогою файлів конфігурації реєстратора та (за потреби) спеціальних класів плагінів. Існує ряд альтернатив, що не існують.

Коротше кажучи, це вирішені проблеми ... для ведення журналів ... і, отже, для їх вирішення не потрібно використовувати ін'єкцію залежності.

Єдиний випадок, коли DI може бути корисним (у порівнянні зі стандартними підходами до ведення журналу), якщо ви хочете піддавати реєстрацію вашої програми одиночному тестуванню. Однак я підозрюю, що більшість розробників скажуть, що ведення журналу не є частиною функціональності класів, а не те, що потрібно перевірити.

@Telastyn пише:

І тоді ви отримаєте аргумент, що сам реєстратор впорається зі зміною. "О, якщо ціль / фільтрування / форматування / стратегія зміниться, ми просто змінимо конфігурацію!" Це сміття. Мало того, що тепер у вас є об'єкт God, який обробляє всі ці речі, ви пишете свій код у XML (або подібному), де не отримуєте статичного аналізу, не отримуєте помилок часу компіляції, і ви не ' t дійсно отримують ефективні одиничні тести.

Боюся, що це дуже теоретичний ріпост. На практиці більшість розробників та системних інтеграторів ПОДАЮТЬ той факт, що ви можете налаштувати ведення журналу через конфігураційний файл. І їм подобається той факт, що від них не очікується перевірка реєстрації модуля.

Звичайно, якщо ви складете конфігурації журналів, то у вас можуть виникнути проблеми, але вони виявляться як відмова програми під час запуску, так і занадто багато / занадто мало журналу. 1) Ці проблеми легко усуваються, виправляючи помилку у файлі config. 2) Альтернативою є повний цикл складання / аналізу / тесту / розгортання кожного разу, коли ви вносите зміни до рівнів реєстрації. Це не прийнятно.


3

Так і Ні !

Так: Я думаю, що розумно, що різні підсистеми (або семантичні шари, або бібліотеки, або інші поняття модульного зв’язку) приймають (той самий або) потенційно різний реєстратор під час їх ініціалізації, а не всі підсистеми, що посилаються на один і той самий спільний синглтон .

Однак,

Ні: водночас нерозумно параметризувати ведення журналів у кожному маленькому об’єкті (за допомогою конструктора чи екземпляра). Щоб уникнути зайвих і безглуздих розривів, більш дрібні об'єкти повинні використовувати одиночний реєстратор свого контексту.


Це одна з причин серед багатьох інших думати про модульність у рівнях: методи згруповані в класи, а класи - у підсистеми та / або семантичні шари. Ці великі пучки є цінним інструментом абстракції; нам слід розглянути різні міркування в модульних межах, ніж при їх перетині.


3

Спочатку він починається з потужного кеш-сингтона, наступні речі, які ви бачите, - це сильні classодиночні клавіші для рівня баз даних, що представляють глобальний стан, не описові API- ес і нестабільний код.

Якщо ви вирішили не мати синглтона для бази даних, мабуть, непогано мати синглтон для кешу, зрештою, вони представляють дуже схожу концепцію зберігання даних, лише використовуючи різні механізми.

Використання одиночного класу в класі перетворює клас, який має певну кількість залежностей, до класу, який теоретично має нескінченну кількість, тому що ніколи не знаєш, що насправді ховається за статичним методом.

За останнє десятиліття, що я проводив програмування, був лише один випадок, коли я став свідком зусиль змінити логіку ведення журналу (який тоді був записаний як одиночний). Тож хоча я люблю уколи залежностей, реєстрація справді не є такою великою проблемою. Кеш, з іншого боку, я б завжди вважав залежність.


Так, реєстрація рідко змінюється, і зазвичай не потрібно бути модулем, який можна змінювати. Однак я одного разу спробував випробувати тест класу помічників ведення журналу, який мав статичну залежність від системи ведення журналу. Я вирішив, що найпростішим механізмом зробити його тестуваним було б запустити тестований клас в окремому процесі, налаштувати його реєстратор для запису в STDOUT та проаналізувати цей вихід у моєму тестовому випадку ಠ_ಠ У мене був подібний досвід роботи з годинниками, де ви ' я, очевидно, ніколи не хочу нічого, окрім реального часу, правда? За винятком випадків тестування футлярів часових поясів / крайових ліній DST, звичайно…
amon

@amon: Годинники схожі на вхід у систему, що вже існує інший механізм, який виконує ті ж цілі, що і DI, а саме Joda-Time та його безліч портів. (Не те, що в використанні DI замість цього нічого поганого; але простіше використовувати Joda-Time безпосередньо, ніж намагатися написати спеціальний адаптер для ін'єкцій, і я ніколи не бачив, щоб хтось це пошкодував.)
ruakh

@amon "У мене був подібний досвід роботи з годинниками, де ви, очевидно, ніколи не хочете нічого, окрім реального часу, правда? За винятком випадків, коли випробовуєте часові пояси / крайні випадки DST ..." - або коли ви зрозумієте, що помилка має пошкоджена ваша база даних, і єдина надія на її повернення - проаналізувати ваш журнал подій та відтворити його, починаючи з останньої резервної копії ... але раптом вам потрібен весь код для роботи на основі часової позначки поточного запису журналу, а не поточного час.
Жуль

3

Так і Ні, але в основному Ні

Я припускаю, що більша частина розмови базується на статичному екземплярі проти введеного екземпляра. Ніхто не пропонує, щоб реєстрація порушила SRP, я припускаю? В основному ми говоримо про "принцип інверсії залежності". Tbh Я здебільшого згоден з невідповіддю Теластина.

Коли добре використовувати статику? Бо однозначно іноді добре. Точка відповідей "так" на користь абстракції, а відповіді "ні" вказують на те, що вони - це те, за що ви платите. Однією з причин вашої роботи є те, що немає однієї відповіді, яку можна записати та застосувати до всіх ситуацій.

Брати: Convert.ToInt32("1")

Я вважаю за краще це:

private readonly IConverter _converter;

public MyClass(IConverter converter)
{
   Guard.NotNull(converter)
   _converter = conveter
}

.... 
var foo = _converter.ToInt32("1");

Чому? Я приймаю, що мені потрібно буде перефактурувати код, якщо мені потрібна гнучкість для заміни коду конверсії. Я погоджуюсь з тим, що я не зможу знущатися над цим. Я вважаю, що простота і лаконічність варті цієї торгівлі.

Дивлячись на інший кінець спектру, якби це IConverterбув a SqlConnection, я був би дуже жахливо бачити це як статичний дзвінок. Причини, які є досить очевидними. Я хотів би зазначити, що в SQLConnectionдодатку може бути досить «наскрізний», тому я б не використовував ці точні слова.

Чи Ведення журналу більше схоже на SQLConnectionчи Convert.ToInt32? Я б більше сказав, як "SQLConnection".

Ви повинні знущатися з Ведення журналів . Він спілкується із зовнішнім світом. Коли я пишу метод, використовуючи його Convert.ToIn32, я використовую його як інструмент для обчислення іншого окремо випробуваного виходу класу. Мені не потрібно перевіряти, чи Convertбуло викликано правильно, коли перевіряли, що "1" + "2" == "3". Ведення журналів відрізняється, це абсолютно незалежний вихід класу. Я припускаю, що це результат, який має значення для вас, команди підтримки та бізнесу. Ваш клас не працює, якщо ведення журналу не правильне, тому одиничні тести не повинні проходити. Ви повинні тестувати, що записує ваш клас. Я думаю, що це вбивчий аргумент, я дійсно міг би просто зупинитися тут.

Я також думаю, що це щось цілком ймовірно, що зміниться. Хороший журнал не просто друкує рядки, це уявлення про те, чим займається ваша програма (я великий прихильник ведення журналів на основі подій). Я бачив, як базовий журнал перетворюється на досить складні інтерфейси звітування. Очевидно набагато простіше в цьому напрямку, якщо ваш лісозаготівля виглядає _logger.Log(new ApplicationStartingEvent())і менш схожим Logger.Log("Application has started"). Можна стверджувати, що це створює інвентар для майбутнього, яке ніколи не може відбутися, це виклик рішення, і я думаю, що воно того варте.

Насправді в особистому проекті я створив інтерфейс без реєстрації, використовуючи лише те, _loggerщоб зрозуміти, що робить додаток. Це означало, що мені не потрібно було писати код, щоб зрозуміти, що робить додаток, і я закінчився рок-сильним журналом. Я відчуваю, що якби моє ставлення до ведення лісозаготівлі було, що це просто і незмінно, ця ідея не сталася б у мене.

Тож я погодився би з Теластином у випадку лісозаготівлі.


Ось як я реєструюсь інцидентно . Я хотів би покластись на статтю чи щось таке, але я не можу її знайти. Якщо ви перебуваєте у світі .NET і шукаєте журнал подій, ви знайдете Semantic Logging Application Block. Не використовуйте його, як і більшість кодів, створених командою MS "Шаблони і спостереження", за іронією долі, це антипаттерн.
Натан Купер

3

Перші проблеми, що перетинаються, не є основними складовими і не повинні розглядатися як залежності в системі. Система повинна працювати, якщо, наприклад, Logger не ініціалізований або кеш не працює. Як ви зробите систему менш сполученою та згуртованою? Ось де SOLID відображається в дизайні OO системи.

Збереження об'єкта як одиночного не має нічого спільного з SOLID. Це ваш життєвий цикл об'єкта, скільки часу ви хочете, щоб об’єкт жив у пам'яті.

Клас, який потребує ініціалізації залежності, не повинен знати, чи наданий екземпляр класу є однотонним або тимчасовим. Але tldr; якщо ви пишете Logger.Instance.Log () у кожному методі чи класі, то це проблематичний код (запах коду / жорстке з'єднання) - справді безладний. Це момент, коли люди починають зловживати SOLID. І такі розробники, як ОП, починають задавати справжнє запитання, як це.


2

Я вирішив цю проблему, використовуючи поєднання успадкування та ознак (які також називаються міксинами в деяких мовах). Характеристики дуже зручні для вирішення такого роду наскрізних проблем. Зазвичай це мовна особливість, тому я думаю, що справжня відповідь полягає в тому, що це залежить від мовних особливостей.


Цікаво. Я ніколи не робив жодної значної роботи, використовуючи мову, яка підтримує риси, але я розглядав можливість використання таких мов для деяких майбутніх проектів, тому мені було б корисно, якщо ви можете розширити цю проблему та показати, як риси вирішують проблему.
Жуль
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.