Я создаю пакет для обработки данных, которые поступают до 4 разных типов. Каждый из этих типов является легитимным классом в виде матрицы, data.frame или дерева. В зависимости от способа обработки данных и других экспериментальных факторов некоторые из этих компонентов данных могут отсутствовать, но все же чрезвычайно полезно иметь возможность хранить эту информацию как экземпляр специального класса и иметь методы, которые распознают другой компонент. данные.
Подход 1:
Я экспериментировал со структурой инкрементного наследования, которая выглядит как вложенное дерево, где каждая комбинация типов данных имеет свой собственный явно определенный класс. Это кажется трудным для расширения для дополнительных типов данных в будущем, а также для новых разработчиков сложно выучить все имена классов, какими бы хорошо организованными они ни были.
Подход 2:
Второй подход заключается в создании единого «мастер-класса», включающего слот для всех 4 типов данных. Чтобы слоты были NULL для экземпляров отсутствующих данных, представляется необходимым сначала определить объединение виртуальных классов между классом NULL
и классом нового типа данных, а затем использовать объединение виртуальных классов в качестве ожидаемого класса для соответствующий слот в мастер-классе. Вот пример (при условии, что каждый класс типа данных уже определен):
################################################################################
# Use setClassUnion to define the unholy NULL-data union as a virtual class.
################################################################################
setClassUnion("dataClass1OrNULL", c("dataClass1", "NULL"))
setClassUnion("dataClass2OrNULL", c("dataClass2", "NULL"))
setClassUnion("dataClass3OrNULL", c("dataClass3", "NULL"))
setClassUnion("dataClass4OrNULL", c("dataClass4", "NULL"))
################################################################################
# Now define the master class with all 4 slots, and
# also the possibility of empty (NULL) slots and an explicity prototype for
# slots to be set to NULL if they are not provided at instantiation.
################################################################################
setClass(Class="theMasterClass",
representation=representation(
slot1="dataClass1OrNULL",
slot2="dataClass2OrNULL",
slot3="dataClass3OrNULL",
slot4="dataClass4OrNULL"),
prototype=prototype(slot1=NULL, slot2=NULL, slot3=NULL, slot4=NULL)
)
################################################################################
Поэтому вопрос можно перефразировать так:
Существуют ли более эффективные и/или гибкие альтернативы любому из этих подходов?
Этот пример изменен с ответа на ТАК вопрос об установке значения слота по умолчанию на NULL. Этот вопрос отличается тем, что мне интересно узнать лучшие варианты в R для создания классов со слотами, которые при необходимости могут быть пустыми, несмотря на то, что во всех других непустых случаях требуется определенный сложный класс.