Просматривая код, который я написал, я наткнулся на следующую конструкцию, которая заставила меня задуматься. На первый взгляд кажется достаточно чистым. Да, в реальном коде getLocation()
метод имеет немного более конкретное имя, которое лучше описывает, в каком именно месте он находится.
service.setLocation(this.configuration.getLocation().toString());
В этом случае service
это переменная экземпляра известного типа, объявленная в методе. this.configuration
происходит от передачи в конструктор класса и является экземпляром класса, реализующего определенный интерфейс (который требует публичного getLocation()
метода). Следовательно, возвращаемый тип выражения this.configuration.getLocation()
известен; конкретно в этом случае это a java.net.URL
, тогда как service.setLocation()
хочет a String
. Поскольку два типа String и URL не совместимы напрямую, требуется какое- то преобразование, чтобы поместить квадратный колышек в круглое отверстие.
Однако , в соответствии с Законом о Деметре , как цитируется в чистом кодексе , метод F в классе C должен вызывать только методы на C , объекты , созданные или передаются в качестве аргументов е , и объекты проведены в переменных экземпляра C . Все, что выходит за рамки этого (последнее toString()
в моем конкретном случае выше, если только вы не рассматриваете временный объект, созданный в результате самого вызова метода, и в этом случае весь Закон кажется спорным) не допускается.
Существуют ли веские причины, по которым вызов, подобный указанному выше, с учетом перечисленных ограничений, должен быть запрещен или даже запрещен? Или я просто слишком придирчив?
Если бы я реализовать метод , URLToString()
который просто вызывает toString()
на URL
объект (например, возвращаемую getLocation()
) , переданного ей в качестве параметра, и возвращает результат, я мог бы обернуть getLocation()
вызов в ней для достижения точно такой же результат; по сути, я бы просто переместил конверсию на один шаг наружу. Это как-то сделает это приемлемым? (Мне кажется , интуитивно, что в любом случае это не должно иметь никакого значения, поскольку все, что нужно, - это немного изменить положение вещей. Однако, следуя приведенной выше букве закона Деметры, это было бы приемлемо, поскольку я будет работать непосредственно с параметром функции.)
Будет ли какая-то разница, если это будет что-то более экзотическое, чем вызов toString()
стандартного типа?
При ответе имейте в виду, что изменение поведения или API типа, к которому относится service
переменная, нецелесообразно. Также, ради аргумента, допустим, что изменение типа возвращаемого значения getLocation()
также нецелесообразно.