Просматривая код, который я написал, я наткнулся на следующую конструкцию, которая заставила меня задуматься. На первый взгляд кажется достаточно чистым. Да, в реальном коде 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()также нецелесообразно.