Подтвердить что ты не робот

"Цепочки сообщений" против "Средний человек"

Я читаю книгу рефакторинга Фаулера, и я немного смущен этим запахами кода.

"Цепочки сообщений" - это вызовы типа a.getB().getC().getValue().

"Средний человек" - это метод, подобный

class A
{
    object getCValue()
    {
        return b.getCValue();
    }
}

Как я понимаю, этот раздел гласит, что если у вас есть "Цепочки сообщений" , вы сокращаете их, вводя "Средних мужчин". И если у вас есть "Средние люди", вы превращаете их в "Цепочки сообщений" ...

Теперь, очевидно, должно быть какое-то ограничение для этого, или у вас будет программист карусели. В какой момент я должен отдавать предпочтение другому?

Один из них связывает класс с несвязанными классами, другой - связывает класс со структурой. Поэтому теоретически мой подход состоял бы в том, чтобы проверить, уменьшает ли какое-либо данное изменение один вид связи больше, чем увеличивает другой тип связи. Но хуже ли один вид сцепления и нужно больше взвешивать? То есть добавьте только одно сцепление класса, если вы можете удалить X структурных муфт?

4b9b3361

Ответ 1

Предпочтительные средние люди над цепочками сообщений также известны как Закон Деметры, который можно суммировать как "говорить только с вашими прямыми зависимостями".

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

Это также помогает с разделением проблем, поскольку код с A и хочет, чтобы C не должен был знать, что есть B. Это помогает модульности.

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

Ответ 2

Как сказал Хаммар, это все о Законе Деметры. Такие вещи, как a.getB().getC().getD(), почти всегда плохие. Они вводят связь с клиентом интерфейса A. Предпочитают ввести среднего человека, например:

class A
    def calculateHowManyCowsCanFitOnTheMoon
        doLocalCalculation(b.performEncapsulatedCalculation())
    end
end

Вы хотите избавиться от Среднего Человека, когда он не выполняет такую ​​задачу, как выше, например, когда он просто извлекает данные из B. Я бы сказал, что рефакторинг для плохого среднего человека может быть Переместить поле/Переместить метод рефакторинг.

Ответ 3

Это ваш выбор. Кодируйте его так, как вы думаете, будет более удобным. Кстати, я не думаю, что есть случай "связывания класса с несвязанными классами". Скорее, это вопрос превращения косвенных отношений в прямое отношение. Особенно это стоит делать, когда вы получаете доступ к косвенному классу несколько раз из своего класса. Это также может удалить некоторые зависимости от промежуточных классов в зависимости от того, как вы устанавливаете прямую связь.