
Потерянная абстракция
Давайте с места в карьер. Представим, что есть программа, которая управляет выдачей книг читателям. За каждым читателем закрепляется полка с книгами, которые ему доступны.
У нас будет класс Reader, который представляет читателя. Он принимает данные о пользователе и полке, привязанной к нему.
Ещё у нас будет код, который использует экземпляр этого класса в условии внизу. В нём мы будем проверять, есть ли определённая книга на полке у этого читателя и может ли он её прочесть.
Вопрос: что не так с этим условием в конце?
class Reader {
constructor(user, shelf) {
this.user = user
this.shelf = shelf
}
getBooksFromShelf = () =>
this.shelf.getBooks()
}
const reader = new Reader(
someUserData,
someBookShelfData)
// вот тут проблема ↓
if (reader.getBooksFromShelf().contains(book.id)) {
// ...
}
На первый взгляд всё, вроде, адекватно, но можно сделать лучше.
Смысл вместо реализации
Сейчас код показывает, как действие реализуется технически, в понятиях структур данных. Техническая реализация обычно многословна и сложна, поэтому понять сразу, что тут происходит, — трудно.
Но как только мы...
// заменим условие на метод-предикат canRead,
// в который вынесем всю техническую реализацию...
if (reader.canRead(book)) {
// ...
}
class Reader {
// ...
canRead = book =>
this.getBooksFromShelf().contains(book.id)
}
...код станет гораздо понятнее.
Говорящий метод
Изменилось мало: мы добавили метод, который скрывает внутри себя то, что раньше находилось в условии. Но благодаря ему мы теперь не говорим, как мы хотим что-то сделать; мы говорим, что мы хотим сделать.
Мы начинаем описывать взаимодействие между сущностями через процессы из предметной области. Такое описание облегчает чтение кода, потому что выражает намерение — чего мы хотим добиться в результате.
Подобный метод похож в какой-то мере на фасад, потому что скрывает подробности реализации за собой. Только в нашем случае мы дополнительно переходим от технического языка к понятиям предметной области, оперировать которыми естественнее и проще при описании процессов в системе.
В книге “97 Things Every Programmer Should Know” есть глава “Code in the Language of Domain”. Она как раз описывает подобные случаи.
Ссылочки, ссылочки, ссылочки
Ютуб, книга, два конспекта и статья: