О читаемости неявных параметров
У всех методов в моем классе DAO, который обрабатывает папки (веб-приложение о облачном хранилище, например, на диске Google), в качестве первого параметра указан пользователь. Этот параметр используется для того, чтобы текущий пользователь имел доступ только к тем папкам, которые ему принадлежат.
Некоторые из примеров:
class FolderDAO {
def findRoot(user: User): Future[Option[DBFolder]] = { /* implementation */}
def findById(user: User, folderId: Long): Future[Option[DBFolder]] = { /* implementation */}
def findChildren(user: User, folder: DBFolder): Future[List[DBFolder]] = { /* implementation */}
}
и так далее.
Есть вероятность, что однажды мне понадобится метод, для которого не нужен параметр User, но он все еще будет в меньшинстве.
Как вы можете себе представить, использование таких методов довольно громоздко.
Я определил 3 решения проблемы:
- Оставьте это как есть, так как читабельность превыше всего
- Пользовательский сервис хранит текущего пользователя и доступен всем другим сервисам (и DAO) (это похоже на глобальную переменную, но сервис инъекционный, поэтому тесты в порядке)
- Неявный пользовательский параметр для этих методов
С последствиями:
def findRoot()(implicit user: User): Future[Option[DBFolder]]
def findById(folderId: Long)(implicit user: User): Future[Option[DBFolder]]
def findChildren(folder: DBFolder)(implicit user: User): Future[List[DBFolder]]
Как вы думаете, это лучший вариант здесь?
Этот пост Stackru дает некоторое представление об этом вопросе, но, к сожалению, мало помогает
1 ответ
Я бы, вероятно, использовал четвертый вариант:
trait UserService {
def findRoot(): Future[Option[DBFolder]]
def findById(folderId: Long): Future[Option[DBFolder]]
def findChildren(folder: DBFolder): Future[List[DBFolder]]
}
def userService(user: User): UserService = ???
Я вообще скептически отношусь к использованию неявных параметров только для сохранения некоторых символов при вызове метода. Это уменьшает ясность для небольшой пользы.