Відповідно до закону Деметра, чи дозволяється класу повернути одного зі своїх членів?
Так, це, безумовно, є.
Давайте розглянемо основні моменти :
- Кожен підрозділ повинен мати лише обмежені знання про інші підрозділи: лише одиниці, "тісно" пов'язані з поточним підрозділом.
- Кожен підрозділ повинен розмовляти лише зі своїми друзями; не розмовляйте з незнайомцями.
- Поговоріть лише зі своїми найближчими друзями.
Усі три з яких залишають вас задати одне запитання: хто друг?
Вирішуючи, що повернути, Закон Деметера або принцип найменшого знання (LoD) не диктує, що ви захищаєтесь від кодерів, які наполягають на його порушенні. Це диктує, що ви не змушуєте кодери порушувати це.
Збентежуючи це саме те, чому так багато хто думає, що сеттер повинен завжди повернутись ні до чого. Ні. Ви повинні дозволити спосіб запитів (гетерів), які не змінюють стан системи. Це основне розділення запиту команд .
Чи означає це, що ви можете заглиблюватися в кодову базу, яка поєднує разом все, що завгодно? Ні. Ланцюг разом, лише те, що було призначено прикувати разом. Інакше ланцюжок може змінитися, і раптом ваш матеріал зламається. Це те, що розуміють друзі.
Довгі ланцюги можуть бути призначені для. Вільні інтерфейси, iDSL, велика частина Java8 та старий хороший StringBuilder призначені для створення довгих ланцюгів. Вони не порушують LoD, оскільки все в ланцюжку має на меті працювати разом і обіцяють продовжувати працювати разом. Ви порушуєте поводження, коли з'єднуєте речі, які ніколи не чули один про одного. Друзі - це ті, хто пообіцяв продовжувати працювати ваш ланцюжок. Друзі друзів цього не зробили.
Крім класів, які були призначені спеціально для повернення об'єктів - наприклад, заводські та будівельні класи - чи нормально метод повернення об'єкта, наприклад, об'єкт, який міститься в одному з властивостей класу, чи чи порушує закон деметера (1) ?
Це лише створює можливість порушити деметер. Це не є порушенням. Це навіть не обов'язково погано.
І якщо це порушує закон деметера, чи має значення, якщо повернутий об'єкт є незмінним об'єктом, який представляє частину даних і не містить нічого, крім одержувачів цих даних (2)?
Незмінне тут добре, але не має значення. Потрапити на речі через довший ланцюжок не покращує його. Що робить його краще - це відокремити отримання від використання. Якщо ви використовуєте, запитайте, що вам потрібно в якості параметра. Не вирушайте на полювання, заглибившись у чужих людей.
У псевдокоді:
Я підозрюю, що закон Деметра забороняє такий зразок, як зазначений вище. Що я можу зробити для того, щоб doSomethingElse () можна було викликати, не порушуючи закон (3)?
Перш ніж я розповім про те, x.doSomethingElse(a)
зрозумійте, що ви в основному написали
b.getA().doSomething()
Тепер, LoD - це не підрахунок точок . Але коли ви створюєте ланцюжок, ви говорите, що знаєте, як отримати A
(за допомогою B
) і знаєте, як користуватися A
. Ну A
і B
краще бути близькими друзями , тому що ви тільки в поєднанні їх разом.
Якщо ви тільки що попросив що - небудь рукою для Вас , A
як річ , яку ви могли б використовувати A
і не хвилювало , звідки вона і B
могла прожити життя щасливим і вільної від вашої одержимості отримувати A
від B
.
Щодо x.doSomethingElse(a)
без деталей, звідки x
взявся, то LoD про це нічого не може сказати.
LoD може сприяти відокремленню використання від будівництва . Але я зазначу, що якщо ви релігійно ставитесь до кожного об'єкта як до непривітного, ви будете застрявати в написанні коду статичними методами. Ви можете побудувати дивовижно складний графік об'єкта в основному таким чином, але в кінцевому підсумку вам доведеться викликати метод на ньому, щоб почати роботу. Ви просто повинні вирішити, хто ваші друзі. Від цього нікуди не діватися.
Так, так, класу дозволяється повертати одного зі своїх членів під LoD. Коли ви це робите, вам слід уточнити, чи відповідає цей член вашому класу, тому що якщо це не так, якийсь клієнт може спробувати приєднати вас до цього класу, використовуючи вас, щоб отримати його перед його використанням. Це важливо, тому що тепер те, що ви повертаєтеся, завжди повинно підтримувати це використання.
Є багато випадків, коли це просто не викликає побоювань. Колекції можуть ігнорувати це просто тому, що вони призначені дружити з усім, що їх використовує. Подібно цінні об’єкти дружні з усіма. Але якщо ви написали утиліту, що підтверджує адресу, яка вимагала від співробітника об'єкта, щоб він вилучив адресу, а тоді просто попросіть адресу, добре ви будете сподіватися, що і працівник, і адреса походять з однієї бібліотеки.