Здравствуйте, samius, Вы писали:
S>Давно думал подискутировать на тему Law of Demeter. Но как-то поводу не возникало.
Ну вот, повод нашелся.
ARK>>Потому что если трактовать википедийное определение буквально, то получается, что у объектов допустимы только функции, не возвращающие значений (void).
ARK>>Ибо если мы вернем что-то, то мы с этим "что-то" не имеем права ничего делать. Выходит, что, к примеру, все фабрики объектов идут лесом.
S>Не совсем так. Это "что-то" можно передать параметром куда-нибудь (в свой метод, в метод объекта, инстанциированного в текущем методе, либо в метод глобального объекта). Запрещается лишь вызывать его метод.
А в чем в таком случае смысл закона? Мы все равно вызываем нужный нам метод, просто "per rectum".
(Аналогично можно и просто присвоить объект в локальную переменную, а потом дернуть метод у этой переменной.)
Но по идее-то LoD, как я его понимаю, запрещает нам оперировать внутренней структурой объекта _в принципе_ (а не только в текущем методе).
ARK>>С другой стороны, мы можем возвращаемое значение записать в поле и тут же у этого поля вызвать метод — это вроде как не будет нарушением закона Деметры. Но выглядит это очень тупо.
S>Согласен. Тупо. Но формально (если мы используем конкретно эти формулировки) и не всякое поле подойдет. Глобальная переменная — подойдет. Поле объекта чей метод выполняется — нет. И это еще более тупо.
Почему же поле текущего объекта не подойдет? Вроде бы не видно в определении чего-то, противоречащего этому.
ARK>>Еще непонятный момент с операторами. Например, в выражении "(a + b) / 3" оператор деления уже нарушает сабж.
S>формально — нет. Дело в том, что оператор деления "/" обычно не метод объекта результата суммы a и b. Вообще, когда мы вызываем статический метод (а оператор деления "/" обычно можно считать именно таковым), закон Деметры неприменим.
Ну а если оператор таки метод объекта? Скажем, в Smalltalk или Eiffel.
Насчет статических объектов... Это по сути вырожденный случай обычных объектов, существующих в одном экземпляре. На мой взгляд, выделять их в отдельную касту не стоит.
S>Все верно, у "ЗАКОН"-а должна быть очень формальная формулировка, которая не допускает кривотолков и разночтений. ИМХО, никаких "придумай себе сам, когда это применять" не допустимо.
+1
S>По поводу мнения, каким бы оно могло быть: думал по этому поводу. Некое рациональное зерно присутствует, но в форме "делай только так и будет счастье" слишком много иррационального. Плодить водопроводные методы a.BMethod() вместо a.b.Method() не видно вообще никакого резона.
Некий резон на самом деле имеется. В первом случае у нас контролируемое изменение объекта, о котором этот объект знает. Во втором мы лезем грязными руками внутрь и можем наломать дров. Видел жуткий говнокод (если конкретно, то во фреймворке MapXtreme), когда объект подписывался на изменения своих собственных полей на разных уровнях вложенности. Это мега-жесть.
S>Особенно если это a.Name.Substring(...) или что-то вроде. Не делать же метод A.NameSubstring(...).
А вот это уже что-то иное. Возможно, граница пролегает либо тут: "у вложенных объектов можно дергать только чистые функции", либо тут: "объект может выставлять наружу только примитивные value-типы, которые можно использовать любым способом".