Comments 2
Вот еще несколько подобных решений, уже описанных на Хабре:
Возможно, сможете что-то почерпнуть оттуда.
В качестве быстрого совета. Обратите внимание, что конфигураторы ячеек у вас имеют абсолютно идентичный код. Их можно привести к дженерику, написать один раз и переиспользовать. По второй ссылке это как раз и реализовано. Только называется оно там фабрикой, если я правильно помню терминологию.
Ну, и объединять 2 ответственности (DataSource и DataDelegate) в 1м классе (SearchTableManager) тоже не лучшее решение, будет сложно переиспользовать код. Аналогично сделано в первой статье. Там же можно поглядеть, к каким сложностям это приводит и как ребята попробовали их решить. В вашем случае все равно придется в каждом экране делать свой менеджер. Если разнести ответственности, то их уже можно переиспользовать отдельно. Например, переиспользовать те же ячейки, но привязать на них уже другие действия.
И последним этапом можно будет еще и развязать экшены действий пользователя по каждому типу ячейки друг от друга. Тогда каждое действие можно будет независимо переиспользовать в любом контроллере. Полученный делегат можно аналогично написать один раз и переиспользовать примерно в 90% случаев. Тут поможет Responder Chain. Статью о том, как responder chain использовать с универсальной реализацией делегата мы готовим. Скоро она появится на Хабре, как продолжение цикла статей из второй ссылки.
В данном случае - разумеется, можно использовать дженерик, но это самый простой случай, в более сложных кейсах там так не получится ввиду разной направленнсти и функциональности ячеек.
Не вижу проблемы в том, чтобы добавить delegate и datasource в один сервис ввиду того, что они не будут изменяться с добавлением ячеек или вроде того. Возможно было бы красиво, но пока считаем это избыточным.
Ну и на практике менеджеры таблиц достаточно легко переиспользовать, что мы и делаем между экранами и проектами со схожей архитектурой =)
Swift TableManager