Ninazu, это метод калькулятора, но именно к шаблону visitor он не относится. может быть и просто методом чисто этого класса, не входящим в другие интерфейсы или родительские классы.
к примеру, эти визиторы могут быть какими-то плагинами графического редактора. массовая заливка другим цветом или массовый ресайз - к ним общая площадь вообще не относится.
Ninazu, не заметил вчера добавление насчет "обрабатываются одинаково"
а и правда, что я имел в виду? похоже, невнимательно читал и думал на момент ответа, что в visit передается IArea и визитор завязан на getArea(). да, фраза как-то не в тему.
Ninazu, про S я уже выше писал, по этому принципу есть расхождение во мнениях. плодить на каждый чих отдельные классы - это тоже перебор. тем более, в нашем случае accept можно вынести в базовый класс, раз он у всех фигур одинаковый.
в традиционном шаблоне элементы как раз не скипают. каждый визитор имеет методы visitClassA, visitClassB и т.д. для всех видов элементов, а элементы в accept дергают соответствующий метод визитора. https://refactoring.guru/design-patterns/visitor
в общем, бесконечный баланс между code smell и оверинжинирингом :)
вообще, getResult и может быть разным. мало ли, будем считать общую площадь цветных или вес шерсти, настриженной с пушистых. а вот собственно к шаблону visitor он отношения не имеет, поэтому в IVisitor ему не место.
но, чтобы жизнь медом не казалась, следует помнить, что этот пример упрощенный (все фигуры обрабатываются одинаково), использование instanceof считается code smell, а традиционный visitor из книжки имеет по отдельному методу на каждый тип элемента, поэтому нарушает принцип O и в книжке специально указано, что он хорошо подходит для случаев, когда добавляются разные операции над элементами, но плохо для случаев, когда добавляются новые типы элементов :)
Flying, зависимости внедряются не только через конструктор. лень гуглить первоисточник, но property injection и method injection точно есть. для constructor injection это как раз неподходящий случай.
насчет жестких связок - я потому и намекнул на принцип D в предыдущем комментарии. если калькуляторы используют Box, это уже проблема (а вдруг считать нужно не только в коробке, а еще в какой-нибудь волшебной шляпе, где фигуры сами возникают после "вжух!"). Box должен реализовывать некий IIterator, тогда мы сможем все от всего отвязать.
Flying, S - принцип неоднозначный. кто-то его трактует, как здесь (класс должен отвечать за один кусок функциональности), кто-то - как Боб Мартин (класс должен иметь только одну причину для изменения). я отношусь ко вторым и в этом плане претензий к классу Box из вопроса вроде нет. он меняется, когда добавляются новые методы подсчета, но не меняется, когда добавляются новые виды фигур.
но потом решил что лучше не захламлять интерфейс чтобы не усложнять логику.
никакого криминала, это dependency injection. будет чуть лучше соответствовать принципу D, чем
interface IFigureCalculator
{
public function calculate(Box $box, ...$args);
}
Ninazu, ну, про visitor это я для примера. здесь достаточно dependency injection, как Flying в конце своего ответа предложил (calculate(IFigureCalculator $calculator, ...$args))
ну не весь же. раз он Box, значит, он хранит фигурки, значит массив shapes это правильно как минимум :)
раз у нас есть задача что-то как-то по этому массиву считать - у нас есть разные "считатели", которые по-разному что-что подсчитывают. выглядит как шаблон Visitor, например.
ну, если так ставить вопрос - все, что не машинный код, было придумано для упрощения и удобства разработки, так что это можно просто вынести за скобки и начать рассматривать то самое "еще что-то" :)
конкретно роль абстрактных классов и интерфейсов в упрощении и удобстве разработки заключается в повторном использовании кода, а именно в композиции объектов, как более гибком решении по сравнению с обычным наследованием
типизация здесь при том, что абстрактные классы и интерфейсы изначально были придуманы в строго типизированном окружении, где компилятор следит за соблюдением контрактов. в слабо типизированных языках, действительно, можно не заморачиваться, просто что-то куда-то передавать и надеяться, что в рантайме не поломается. судя по вопросу, разработчики php решили, что эти сущности настолько полезны, что нужно их добавить в язык. значит, оно того стоит :)
Не вижу, чтобы этот код как-то влиял на скорость загрузки. Для начала откройте в браузере developer tools и во вкладке network гляньте, что там грузится, сколько времени занимает.
Роман Ахмадуллин: Ах, оставьте, я тоже за все хорошее против всего плохого, честно-честно! :)
Если не секрет, раз уж Вы сами начали про регалии, о каких приложениях идет речь? Сколько человек в команде? Что-нибудь выставлено в интернет, можно посмотреть?
Роман Ахмадуллин: В основном соглашусь. Но это тоже про сферического system architect в вакууме. Немногие фирмы имеют такие проекты с такими бюджетами. Фреймворк - системный архитектор/тимлид для бедных.
Роман Ахмадуллин: статью видел, тоже не понравилась :)
Там про сферического программиста в вакууме, который в основном пишет в одиночку, не факт, что потом свой код поддерживает, ну и никому его не передает.
Насчет магического кода согласен, потому-то мне не понравился ангулар.
Насчет траты времени - ну, тут больше половины академического интереса, так что все нормально, реально для таких вещей мне и голого jquery хватает.