While both approaches work to some extent, I'd actually suggest method 2. 'Standard' object-oriented considerations about 'is-a' versus 'has-a' designs generally fall out in favor of 'has-a'. Further, in R methods can be added to objects at any time, so in some ways 'is-a' is advertising that it makes sense to do any number of perhaps arbitrary things to your class. This is a hard contract to fulfill, even for defined functions like sub-setting -- presumably if the user drops / adds rows or columns to the underlying data
in formhubData
, you'd like to update the information in form
.
Instead, it seems like you'd really like to implement a 'has-a' relationship, and use the opportunity to restrict the interface to operations that make sense. You can still get substantial code re-use with minimal new code by simple dispatch to underlying implementations, e.g.,
setMethod(dim, "formhubData", function(x) dim(x@data)
gives you nrow
and ncol
, for instance. For common operations (e.g., subsetting), you'd like to provide implementations that respect the integrity of your data structure. And if it really is the case that the user should be able to do pretty much arbitrary things, you can provide simple 'accessors' to data
, perhaps using the setter to do whatever is required to bring the form
field into line with the updated data.frame provided by the user.