2013-12-18 3 views
1

Я пытаюсь понять концептуальные последствия предоставления функционального пользовательского интерфейса для ссылочных классов (или действительно классов S4/S3). Короче говоря, я обеспокоен тем, что если я напишу код, который выглядит так, как показано ниже, то это эквивалентно написанию функционального кода.Функциональные интерфейсы для ссылочных классов

Вот простой линейная регрессия класс:

linRegClass = setRefClass('linRegClass', 
          fields = list(formulaReg = 'formula', 
             dataReg = 'data.frame'), 
          methods = list(doReg = function() { 
          lm(.self$formulaReg, data = .self$dataReg) 
          })) 

linRegInstance = linRegClass$new(dataReg = cars, 
        formulaReg = as.formula(speed ~ dist)) 
linRegInstance$doReg() 
class(linRegInstance) 

Объектно-ориентированный интерфейс не очень удобный, так как в Martin Morgan's slides, напишу функциональный пользовательский интерфейс для базового опорного класса:

fnLinReg = function(formulaReg, dataReg) { 
    linRegInstance = linRegClass$new(formulaReg = formulaReg, 
            dataReg = dataReg) 
    linRegInstance$doReg() 
} 

## use the functional interface 
fnLinReg(dataReg = cars, formulaReg = as.formula(speed ~ dist)) 

Теперь этот функциональный интерфейс наблюдаемо эквивалентна чисто функциональной

fnLinReg2 = function(formulaReg, dataReg) { 
    lm(formula = formulaReg, data = dataReg) 
} 

## use the pure function 
fnLinReg2(dataReg = cars, formulaReg = as.formula(speed ~ dist)) 

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

Любые подробные примеры очень помогли бы.

+0

Ваш пример очень смущен. Любой тип OO плохо для этого примера: вы не сохраняете класс и позже используете его методы, вам просто нужен вызов 'lm', поэтому, конечно, чистая функция будет лучше. –

ответ

1

Сложные конструкторы могут быть определены с использованием метода initialize, который будет вызываться автоматически при вызове new. Я изменил свой пример, чтобы содержать метод инициализации, и новое поле для хранения результата регрессии, потому что initialize всегда будет возвращать referenceClass:

linRegClass = setRefClass('linRegClass', 
          fields = list(formulaReg = 'formula', 
             dataReg = 'data.frame', 
             result = 'lm'), 
          methods = list(doReg = function() { 
          lm(.self$formulaReg, data = .self$dataReg) 
          }, 
          initialize = function(formulaReg, dataReg, ...) { 
          formulaReg <<- formulaReg 
          dataReg <<- dataReg 
          result <<- .self$doReg() 
          })) 

Итак, теперь мы просто имеем:

linRegInstance <- linRegClass$new(dataReg = cars, 
            formulaReg = as.formula(speed ~ dist)) 
linRegInstance$result 
+0

менее подробные имена переменных и имена классов также помогут! –

+0

Ха, я отказываюсь использовать менее описательные имена переменных. ;) Спасибо за Ваш ответ. Не могли бы вы привести пример более сложного примера, где смысл взаимодействия с ссылочным классом имеет смысл? – tchakravarty

+0

Имеет смысл использовать его, когда у вас есть объект, а не функция. Как определенный тип данных или набор данных (если у вас есть набор общих анализов, которые вы хотите выполнить). –

 Смежные вопросы

  • Нет связанных вопросов^_^