Динамика восновном достигается разбиением на методы, например, по типу переданного параметра, в том числе и через регурярные выражения. Повторюсь, метод в URL указывается далеко не всегда. То есть ссылки типа
http://example.com/goods/231
где маска маршрута будет несложно догадаться какая. =) Что-нибудь вида /goods/{int} => goods->show($param)
А вот на поиск товаров: /goods/{string} => goods->search($param)
В целом, конечно, ты отчасти прав: подход не является панацеей. Но делает работу с проектом значительно удобнее. При грамотном составлении маршрутов, разделении на методы, правильном выделении элементов в динамику. Правильное значит не изменяющееся со временем. Действительно, метод search, скорее всего, при любых обстоятельсвах, будет принимать на вход строку, а не ID-шник. Хотя могут быть исключения, не будем фантазировать, сейчас главное принцип. =)
Есть еще
разделение по HTTP методам. Как минимум везде присутствует деление на GET и POST, во всех роутерах что я видел. =) Тоже очень мощный инструмент разбивки по разным обработчикам.
В конце-концов, если нам предстоит исправить даже 100 строк в одном месте, это совсем не тоже самое, как в 100-а различных файлах - темплейтах. Где ссылки разбросаны по HTML, бывает в конструкциях логики отображения, да в каждом файле встречаются по несколько раз.