Абстракция далеко от реализации структуры данных детализирует в Clojure

Я разрабатываю сложную структуру данных в Clojure с несколькими подструктурами.

Я знаю, что захочу расширить эту структуру со временем и могу время от времени хотеть изменить внутреннюю структуру, не повреждая различных пользователей структуры данных (например, я могу хотеть изменить вектор в hashmap, добавить некоторую структуру индексации по причинам производительности или включить тип Java),

Мои существующие взгляды:

  • Определите протокол для полной структуры с различными методами доступа
  • Создайте мини-библиотеку функций, которые перемещаются по структуре данных, например, (abc подструктуры запроса param1 param2)
  • Реализуйте структуру данных с помощью defrecord или deftype с методами протокола, определенными для использования мини-библиотеки

Я думаю, что это будет работать, хотя я волнуюсь, что это начинает быть похожим на слишком большое количество кода "связующего звена". Также это, вероятно, также отражает мое большее знакомство с объектно-ориентированными подходами.

Что рекомендуемый путь состоит в том, чтобы сделать это в Clojure?

14
задан mikera 24 June 2010 в 13:26
поделиться

1 ответ

Я думаю, что deftype может быть выходом, однако я бы пропустил методы доступа. Вместо этого рассмотрите clojure.lang.ILookup и clojure.lang. Associative; это интерфейсы, которые, если вы реализуете их для своего типа, позволят вам использовать get / get-in и assoc / assoc-in, что делает решение гораздо более универсальным (вы сможете не только изменить базовую реализацию, но и, возможно, использовать функции, построенные поверх стандартной библиотеки коллекций Clojure для работы с вашими структурами).

Пара моментов, на которые следует обратить внимание:

  1. Вам, вероятно, следует начать с defrecord, используя get, assoc и Co. со стандартными defrecord реализациями ILookup, Associative, IPersistentMap и java.util.Map. Вы можете пойти с этим довольно далеко.

    Если/когда этого будет недостаточно, посмотрите исходники emit-defrecord (частная функция, определенная в core_deftype.clj в исходниках Clojure). Она довольно сложная, но это даст вам представление о том, что вам может понадобиться реализовать.

  2. Ни deftype, ни defrecord в настоящее время не определяют никаких фабричных функций для вас, но вы, вероятно, должны сделать это сами. Проверка правильности идет внутри этих функций (и/или соответствующих тестов).

  3. Более концептуально сложные операции, конечно, идеально подходят для протокольных функций, построенных на фундаменте get и Co.

О, и посмотрите на gvec.clj в исходниках Clojure для примера того, как может выглядеть серьезный код структуры данных, написанный с использованием deftype. Сложность здесь иного рода, чем та, которую вы описали в вопросе, но, тем не менее, это один из немногих примеров программирования пользовательских структур данных в Clojure, доступных в настоящее время для публичного потребления (и это, конечно, код отличного качества).

Конечно, это только то, что подсказывает мне моя интуиция на данный момент. Я не уверен, что на данном этапе существует много устоявшихся идиом, учитывая, что deftype еще не был выпущен и т.д. :-)

.
11
ответ дан 1 December 2019 в 15:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: