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

Свободные интерфейсы нарушают Закон Деметры?

статья в википедии о Закон Деметры говорит:

Закон можно сформулировать просто как "использовать только одну точку".

Однако простой пример свободный интерфейс может выглядите так:

static void Main(string[] args)
{
   new ZRLabs.Yael.Pipeline("cat.jpg")
        .Rotate(90)
        .Watermark("Monkey")
        .RoundCorners(100, Color.Bisque)
        .Save("test.png");
}

Так происходит ли это вместе?

4b9b3361

Ответ 1

Ну, короткое определение закона слишком сильно сокращает его. Настоящий "закон" (на самом деле совет по хорошему дизайну API) в основном говорит: "Только объекты доступа, которые вы создали сами, или были переданы вам в качестве аргумента. Не допускайте косвенного доступа к объектам через другие объекты. Способы свободных интерфейсов часто возвращают сам объект, поэтому они не нарушают закон, если вы снова используете объект. Другие методы создают для вас объекты, поэтому нет никаких нарушений.

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

Ответ 2

Не обязательно. "Использовать только одну точку" - это неточное резюме Закона Деметры.

Закон Деметры запрещает использование нескольких точек, когда каждая точка представляет результат другого объекта, например:

  • Первая точка - это метод, вызываемый из ObjectA, возвращающий объект типа ObjectB
  • Следующая точка - это метод, доступный только в ObjectB, возвращающий объект типа ObjectC
  • Следующая точка - свойство, доступное только в ObjectC
  • ad infinitum

Однако, по крайней мере, по моему мнению, Закон Деметры не нарушается, если объект возврата каждой точки все тот же тип, что и исходный вызывающий:

var List<SomeObj> list = new List<SomeObj>();
//initialize data here
return list.FindAll( i => i == someValue ).Sort( i1, i2 => i2 > i1).ToArray();

В приведенном выше примере как FindAll(), так и Sort() возвращают тот же тип объекта, что и исходный список. Закон Деметры не нарушается: список только говорил с его ближайшими друзьями.

Говорят, что не все свободные интерфейсы нарушают Закон Деметры, до тех пор, пока они возвращают тот же тип, что и их вызывающий.

Ответ 3

Да, хотя вам нужно применить некоторый прагматизм к ситуации. Я всегда принимаю Закон Деметры как руководство, а не правило.

Конечно, вы можете избежать следующего:

CurrentCustomer.Orders[0].Manufacturer.Address.Email(text);

возможно заменить на:

CurrentCustomer.Orders[0].EmailManufacturer(text);

Поскольку многие из нас используют ORM, который обычно представляет весь домен в качестве графического объекта, может возникнуть идея определить приемлемую "область" для определенного объекта. Возможно, мы должны принять закон demeter, чтобы предположить, что вы не должны отображать весь график как достижимый.

Ответ 4

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

Свободные интерфейсы являются приемлемым исключением из закона, поскольку они означают, чтобы быть хотя бы несколько тесно связанными, поскольку все свойства и методы - это термины мини-языка, которые составлены вместе с формы функциональных предложений.

Ответ 6

Нет проблем с вашим примером. В конце концов, вы вращаетесь, водяные знаки и т.д.... всегда одно и то же изображение. Я считаю, что вы все время общаетесь с объектом Pipeline, так как ваш код зависит только от класса Pipeline, вы не нарушаете LoD.