Закон Деметры гласит следующее:
- Каждый юнит должен иметь только ограниченные знания о других юнитах: только юниты, «тесно» относящиеся к текущему юниту.
- Каждый юнит должен разговаривать только со своими друзьями; не разговаривай с незнакомцами
- Поговорите только со своими непосредственными друзьями.
В C # 6.0 введен новый оператор, называемый нулевым условным оператором . ИМХО, это облегчает кодирование и улучшает читабельность. Но это также облегчает написание более связанного кода, так как легче перемещаться по полям класса, уже проверяя на ничтожность (что-то вроде var x = A?.B?.C?.D?.E?.F?
).
Правильно ли утверждать, что этот новый оператор противоречит Закону Деметры?
c#
design-patterns
object-oriented-design
Артур Риццо
источник
источник
A?.B?.C?.D?.E?.F?
это нарушит его - LoD не о том, сколько точек, и если вызывающий метод имеет такую информацию о структуре, которая не нарушает его точек, такой вызов будет вполне приемлемым. Что такое код может нарушить LoD не достаточно , чтобы сказать , что все виды использования него делают нарушают Lod.X.Y.Z.W.U
является нарушением «закона». Но, по моему опыту работы с кодом, 90% времени это просто уродливый код..?
больше не нарушает LoD чем+
или-
делает.Ответы:
Нет *
* Нулевой условный оператор - это инструмент в языке и .NET Framework. Любой инструмент имеет возможность злоупотребления и использования таким образом, который может нанести ущерб ремонтопригодности данного приложения.
Но тот факт , что инструмент может быть ругали не обязательно означает , что он должен быть оскорбленными, ни того, что инструмент нарушает какие - либо конкретный принцип (ы) , который может быть проведен.
Закон Деметры и другие являются руководством о том, как вы должны написать свой код. Он нацелен на людей, а не на инструменты. Поэтому тот факт, что язык C # 6.0 имеет новый инструмент, не обязательно влияет на то, как вы должны писать и структурировать свой код.
С любым новым инструментом, вам нужно оценить это как ... если парень , который заканчивает тем , что поддержание вашего кода будет жестоким психопатом ... . Обратите внимание, что это руководство для человека, пишущего код, а не об используемых инструментах.
источник
foo = new FiveDMatrix(); foo.get(0).get(0).get(0).get(0).set(0,1);
было бы хорошо (и не хуже, чемfoo[0][0][0][0][0] = 1
) ... и множество других ситуаций, где такое не нарушает LoD.Dom file = prase("some.xml"); file.get(tag1).getChild().get(tag2).getChild() ...
- это проблема обработки структуры какого-то глупого кода. Это не незнакомец ... это просто глупо. Это.?
становится очень полезным в таких структурах.Вроде.
Если вы делаете только один доступ (
a?.Foo
), то это эквивалентно:с которым согласится большинство людей, не является нарушением закона Деметры. В этот момент это просто синтаксический сахар для улучшения читабельности.
Больше, чем это, и это, вероятно, нарушит закон Деметры, и эта функция, как правило, способствует такого рода использованию. Я бы даже сказал, что одного только вышеупомянутого «хорошего» использования недостаточно, чтобы оправдать такого рода изменения в языке, поэтому я ожидаю, что оно было сделано для поддержки менее явно хорошего использования.
Тем не менее, стоит помнить, что Закон Деметры не является законом как таковым, а скорее ориентиром. Много кода нарушает его и работает хорошо. Иногда простота дизайна или кода стоит больше, чем риск, связанный с нарушением закона Деметры.
источник
a?.Func1(x)?.Func2(y)
оператор объединения нулей - это нечто другое.Нет. Давайте рассмотрим как самого оператора, так и интенсивное использование для него.
Само по себе
.?A
зависит от того же объема знаний о классе, который имеет левое значение, и о типе, возвращаемом методом.A != null
, а именно: viz. Необходимо знать, чтоA
свойство существует и возвращает значение, с которым можно сравнитьnull
.Мы можем только утверждать, что это нарушает закон Деметры, если типизированные свойства делают. Мы даже не обязаны иметь
A
конкретный тип (его значение может быть производного типа). Связь здесь минимальная.Теперь давайте рассмотрим
var x = A?.B?.C?.D?.E?.F
.Это означает, что он
A
должен иметь тип, который может иметь значение NULL или иметьB
свойство, которое должно иметь тип, который может иметь значение NULL или иметьC
свойство, и так далее, пока типE
свойства не будет иметь значение, которое может быть NULL или может иметьF
собственность.Другими словами, мы должны делать это либо со статически типизированным языком, либо наложить ограничения на типы, которые могут быть возвращены, если типизация свободна. C # в большинстве случаев использует статическую типизацию, поэтому мы ничего не изменили.
Если бы мы имели тогда, следующий кодекс также нарушил бы закон:
Что точно так же . Этот код, использующий связывание различных элементов, должен «знать» о полной цепочке связывания, но при этом он использует код, который не нарушает Закон Деметры, так как каждый блок имеет четко определенную связь с следующий.
источник
var x = A?.B?.C?.D?.E?.F
всех этих if / elses, даже если в конце они одинаковы.A?.B?.C?.D?.E?.F
так, потому что меньше может быть неправильным; либо мы должны пытаться пройтиF
по этому пути, либо мы не должны этого делать , в то время как в более длинной форме могут быть ошибки, а также ошибка, которая не является правильной.A.B.C.D
. Гораздо проще иметь одну вещь, на которую нужно обращать внимание (доступ к цепочечному свойству), а не две разные вещи, которые зависят от довольно нерелевантных деталей (проверка на ноль)Объект может быть создан с целью инкапсуляции поведения или хранения данных, а объекты могут быть созданы с целью совместного использования с внешним кодом или хранения их создателем в частном порядке.
К объектам, которые создаются с целью инкапсулирования поведения (совместно используемого или нет) или для совместного использования с внешним кодом (независимо от того, инкапсулируют ли они поведение или данные), обычно следует получать доступ через их поверхностный интерфейс. Однако, когда объекты, содержащие данные, создаются для использования исключительно их создателем, обычные причины закона-де-метра для избежания «глубокого» доступа не применяются. Если часть класса, которая хранит или манипулирует данными в объекте, изменяется таким образом, что потребуется корректировка другого кода, можно будет гарантировать, что весь такой код будет обновлен, потому что - как отмечено выше - объект был создан для эксклюзивное использование одного класса.
Пока думаю что? Оператор, возможно, мог бы быть лучше спроектирован, существует достаточно ситуаций, когда объекты используют вложенные структуры данных, и у оператора есть много вариантов использования, которые не будут нарушать принципы, выраженные Законом Деметры. Тот факт, что он может быть использован для нарушения LoD, не должен рассматриваться как аргумент против оператора, поскольку он не хуже, чем "." оператор в этом отношении.
источник