Мне трудно решить, является ли использование defrecord
правильным выбором и, в более широком смысле, если мое использование протоколов в моих записях является семантическим и функциональным.
В моем текущем проекте я создаю игру, в которой есть разные типы врагов, у всех одинаковый набор действий, причем эти действия могут быть реализованы по-разному.
Исходя из опыта ООП, я хочу сделать что-то вроде:
(defprotocol Enemy
"Defines base function of an Enemy"
(attack [this] "attack function"))
(extend-protocol Enemy
Orc
(attack [_] "Handles an orc attack")
Troll
(attack [_] "Handles a Troll attack"))
(defrecord Orc [health attackPower defense])
(defrecord Troll [health attackPower defense])
(def enemy (Orc. 1 20 3))
(def enemy2 (Troll. 1 20 3))
(println (attack enemy))
; handles an orc attack
(println (attack enemy2))
;handles a troll attack
На первый взгляд, это имеет смысл. Я хочу, чтобы у каждого врага всегда был метод атаки, но фактическая реализация этого должна иметь возможность варьироваться в зависимости от конкретного врага. Используя extend-protocol
, я могу создать эффективную отправку методов, которые различаются для моих врагов, и я могу легко добавлять новые типы врагов, а также функционально изменять эти типы.
Проблема, с которой я столкнулся, заключается в том, почему я должен использовать запись вместо общей карты? Вышесказанное мне кажется немного ООП, и мне кажется, что я иду против более функционального стиля. Итак, мой вопрос разбит на два:
- Является ли моя описанная выше реализация записей и протоколов надежным вариантом использования?
- В более общем смысле, когда запись предпочтительнее карты? Я читал, что вам следует отдавать предпочтение записям, когда вы перестраиваете одну и ту же карту несколько раз (как и я в этом случае). Это логично?