View source: R/DecoratorClass.R
DecoratorClass | R Documentation |
Creates a decorator R6 class by placing a thin wrapper around R6::R6Class which allows the constructed class to inherit the fields and methods of the given object.
The decorator design pattern allows methods to be added to an object without bloating the interface with too many methods on construction and without causing large inheritance trees. A decorator class contains fields/methods that are 'added' to the given object in construction, this is made clearer in examples.
There are three possibilities when trying to decorate an object with a field/method that already exists:
exists = "skip"
(default) - This will decorate the object with all
fields/methods that don't already exist
exists = "error"
- This will throw an error and prevent the
object being decorated
exists = "overwrite"
- This will decorate the object with all
fields/methods from the decorator and overwrite ones with the same name
if they already exist
Decorators are currently not cloneable.
All arguments of R6::R6Class can be used as usual, see full details at R6::R6Class.
Gamma, E., Helm, R., Johnson, R., & Vlissides, J. (1996). Design Patterns: Elements of Reusable Software. Addison-Wesley Professional Computing Series (p. 395).
decorate
library(R6) ## Create two decorators # Works with active bindings... dec1 <- DecoratorClass("dec1", active = list(hi = function() "Hi World")) # And public fields... dec2 <- DecoratorClass("dec2", public = list(goodbye = "Goodbye World")) ## Create an object to decorate oop <- ooplah$new() oop$hello() ## Decorate with dec1 by constructing dec1 with object oop: dec_oop <- dec1$new(oop) # equiv `decorate(oop, dec1)` ## We have all original methods from oop dec_oop$hello() # It's inherited methods dec_oop$init # And now decorated methods dec_oop$hi ## We can decorate again redec_oop <- dec2$new(dec_oop) redec_oop$hello() redec_oop$init redec_oop$hi # And now redec_oop$goodbye # Notice the class reflects all decorators, the original object and parents, # and adds the 'Decorator' class class(redec_oop) ## Decorators also work with inheritance parent_dec <- DecoratorClass("parent_dec", public = list(hi = function() "Hi!")) child_dec <- DecoratorClass("child_dec", inherit = parent_dec) dec_oop <- child_dec$new(ooplah$new()) dec_oop$hi() ## Three possibilities if the method/field name already exists: oop <- ooplah$new() exists_dec <- DecoratorClass("exists_dec", public = list(hello = function() "Hi!")) # 1. skip (default) oop$hello() exists_dec$new(oop, exists = "skip")$hello() # 2. error ## Not run: exists_dec$new(oop) exists_dec$new(oop, exists = "error") ## End(Not run) # 3. overwrite oop$hello() exists_dec$new(oop, exists = "overwrite")$hello() ## Cloning # Note that by default the decorated object is not cloned dec <- DecoratorClass("dec", active = list(hi = function() "Hi World")) dec_oop <- dec$new(oop) dec_oop$logically oop$logically <- FALSE dec_oop$logically
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.