Закон Деметры также учитывает стандартные классы?
Предполагая следующий код:
requiredIssue.get().isDone()
где requiredIssue
не является обязательным, и было проверено, что requiredIssue.isPresent()
, Этот код нарушает закон Деметры? Технически, сейчас существует тесная связь между моим классом и факультативным, потому что isDone()
теперь опирается на get()
работает правильно. Но разве не разумно предположить, что стандартная библиотека работает последовательно?
3 ответа
Первый,
requiredIssue.get().isDone()
нарушает закон Деметры, который четко перечисляет объекты, на которых вы можете вызывать методы. Какой бы объект get()
возврата нет в этом списке. Подробнее о самом Законе см. В этой статье.
Во-вторых, конкретный пример с Optional
, призвание get()
из Optional
имеет много проблем и их следует избегать. Закон Деметры (который является своего рода канарейкой в шахте для плохого кода) правильно указывает на то, что эта конструкция ошибочна. Проблемы варьируются от временной связи с isPresent()
вызов, техническая утечка того, чтобы позвонить isPresent()
во-первых, к копированию логики isPresent() по всему месту. Большую часть времени, если вы чувствуете необходимость использования get()
Вы уже делаете это неправильно.
В-третьих, более общий вопрос о том, должны ли стандартные классы быть в основном освобождены от закона Деметры. Они не должны быть освобождены, если вы пытаетесь заниматься объектно-ориентированным программированием. Вы должны иметь в виду, что некоторые JDK и большинство JEE на самом деле не предназначены для использования в объектно-ориентированной среде. Конечно, они используют Java, который является полуобъектно-ориентированным языком, но ожидается, что они будут использоваться в контексте "смешанной парадигмы", в котором разрешены процедурные схемы. Просто подумайте о классах "Служба", чистых объектах "Данные" (таких как Бины), о слоях и т. Д. Они происходят из нашего процедурного прошлого, которое, как утверждают некоторые, все еще актуально и полезно сегодня.
Независимо от того, где вы участвуете в этой дискуссии, некоторые стандартные классы / библиотеки / спецификации просто несовместимы с Законом Деметры или объектно-ориентированной в целом. Если вы готовы пойти на компромисс по объектно-ориентированным принципам (как и большинство проектов), это не проблема. Если вы на самом деле не желаете идти на компромисс в отношении хорошего дизайна, но вынуждены это делать библиотеками или стандартными классами, решение состоит не в том, чтобы обсуждать Закон Деметры, а в том, чтобы признать (и принять), что вы делаете сознательный решение нарушать это.
Итак, разумно ли предположить, что стандартная библиотека работает? Конечно! Это не означает, что они освобождаются от хороших принципов проектирования, таких как закон Деметры, если вы действительно хотите придерживаться объектной ориентации.
На практике закон Деметры означает, что если у вас есть класс или функция, которая зависит от значения isDone()
не проходи requiredIssue
к этому классу или функции. Вы должны просто передать значение isDone()
, Если вы обнаружите, что следование этому принципу приводит к увеличению количества полей или параметров, вы, вероятно, нарушаете принцип единой ответственности.
Закон Деметры применяется слабо и на системных границах (почти никогда на уровне объектов, иногда на уровне модулей).
Это проблема только тогда, когда вы вынуждены сделать «общедоступным» класс в вашем модуле/системе, который в противном случае не должен был бы быть общедоступным. ИМХО Совершение этой ошибки является и/или должно быть редким, и избегайте этого по здравому смыслу, даже для разработчиков среднего уровня.
Как видите, стандартные классы (или .Net:framework/core) НЕ являются нарушением, потому что часто объекты, которые вы видите в их двойных точках, в любом случае должны быть общедоступными.
Подумайте о дизайне. Если вы следуете принципам GRASP (и DDD) при выборе типов объектов для создания, LOD исчезнет и приведет к увеличению связанности.
Это нюанс, LOD не полная чушь, он просто бесполезен, и его лучше игнорировать, решая неясные проблемы, которые он предназначен решать, используя решения (GRASP,DDD), которые устраняют основную причину, а не просто объявляют вне закона симптомы.
Больше чтения от людей в Интернете, которые также согласны со мной (что должно означать, что я прав, а?)
https://www.tedinski.com/2018/12/18/the-law-of-demeter.html
https://naildrivin5.com/blog/2020/01/22/law-of-demeter-creates-more-problems-than-it-solves.html