% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/DecoratorClass.R
\name{DecoratorClass}
\alias{DecoratorClass}
\title{Create an abstract R6 Class}
\description{
Creates a decorator R6 class by placing a thin wrapper around \link[R6:R6Class]{R6::R6Class}
which allows the constructed class to inherit the fields and methods of
the given object.
}
\details{
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:
\enumerate{
\item \code{exists = "skip"} (default) - This will decorate the object with all
fields/methods that don't already exist
\item \code{exists = "error"} - This will throw an error and prevent the
object being decorated
\item \code{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 \link[R6:R6Class]{R6::R6Class} can be used as usual, see full
details at \link[R6:R6Class]{R6::R6Class}.
}
\examples{
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
\dontrun{
exists_dec$new(oop)
exists_dec$new(oop, exists = "error")
}

# 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

}
\references{
Gamma, E., Helm, R., Johnson, R., & Vlissides, J. (1996).
Design Patterns: Elements of Reusable Software.
Addison-Wesley Professional Computing Series (p. 395).
}
\seealso{
\link{decorate}
}
