Коротко:
self.a.b.Method() #<- не корректно. Текущий класс знаком с 'a' но не знаком с 'b' и не должен вызывать ее методы self.a.Method() # <-является корректным. Текущий класс знаком с 'a' (текущий класс _имеет_ а) и может вызывать ее функции.
Минусы:
В 'a' необходимо будет добавить вызов def Method(): self.b.Method() что по сути является проксированием. Это засоряет интерфейсы класса методами пустышками.
Плюсы:
Основная задача закона, избавить программиста от страха к изменению кода. К примеру, представим 2 разные ситуации: 1. В проекте игнорируется закон Деметра. Класс b включен в классы a, c и d. Каждый класс инстанцируется в разных 10 участках кода и применяется a.b.Method(), c.b.Method() и d.b.Method() 2. В проекте применяется закон Деметра. Класс b включен в классы a, c и d. Каждый класс инстанцируется в разных 10 участках кода и применяется a.Method(), c.Method() и d.Method() Представим, что 'b' класс это устаревшая библиотека и поставлена задача заменить эту библиотеку более новой 'z' библиотекой, с другими методами, аргументами и т.д. В 1-ом варианте, нам придется найти 30 участков кода и заменить a.b.Method() на a.z.NewCoolMethod(arg). (В качестве ленивой альтернативы, мы можем создать адаптер, но это загрязняет код) Во 2-ом варианте, нам придется изменить 3 метода a.Method(), c.Method() и d.Method() переопределив в них def Method(): self.z.NewCoolMethod(arg). 30 инстантов продолжат свою работу без изменений Если мы сделаем ошибку в 1-ом варианте и исправим 28 из 30 инстантов, то в 2-ух местах будут оставлены мало заметные ошибки, которые могут проявится со временем и на устранение каждой из них уйдет по часу, так как ошибки в 2-ух местах проявятся в разное время и могут решаться разными программистами. Если мы сделаем ошибку во 2-ом случае и исправим 2 или 1 из 3 методов, то 10-20 инстантов из 30 отпадут и это хорошо. Ошибка будет более выражена, замечена в более ранние сроки. Вероятность того, что ошибка будет устранена за один приход, одним программистов увеличивается.
http://toster.ru/q/44822 http://ru.wikibooks.org/wiki/%D0%9D%D0%B5%D1%81%D0%B2%D1%8F%D0%B7%D0%BD%D0%BE%D1%81%D1%82%D1%8C_%D0%B8_%D0%B7%D0%B0%D0%BA%D0%BE%D0%BD_%D0%94%D0%B5%D0%BC%D0%B5%D1%82%D1%80%D0%B0
Encapsulation and Information Hiding Separation of Concerns (SoC) High Cohesion Low/Loose coupling Convention over Configuration (CoC) Command-query separation (CQS) Design by Contract (DbC) Dependency Injection (DI) Inversion of Control (IoC) Avoid Fragile Baseclass Has-a Is-a What is Identity Interchangeability Option-operand separation Intention Revealing Names Zero Friction Development Encapsulate Variation Composition over inheritance Common Closure Principle Classes that change together must be placed in the same package. Program to an interface, not an implementation You Ain’t Gonna Need It (YAGNI) Keep It Simple, Stupid (KISS)