Forwarding (object-oriented programming)


In object-oriented programming, forwarding means that using a member of an object results in actually using the corresponding member of a different object: the use is forwarded to another object. Forwarding is used in a number of design patterns, where some members are forwarded to another object, while others are handled by the directly used object. The forwarding object is frequently called a wrapper object, and explicit forwarding members are called wrapper functions.

Delegation

Forwarding is often confused with delegation; formally, they are complementary concepts. In both cases, there are two objects, and the first object uses the second object, for example to call a method. They differ in what self refers to on the receiving object : in delegation it refers to the sending object, while in forwarding it refers to the receiving object. Note that self is often used implicitly as part of dynamic dispatch.
For example, given the following code:

// Sender
void n
// Receiver
void m
void n

under delegation this will output m2, n1 because n is evaluated in the context of the original object, while under forwarding this will output m2, n2 because n is evaluated in the context of the receiving object.
In casual use, forwarding is often referred to as "delegation", or considered a form of delegation, but in careful usage they are clearly distinguished by what self refers to. While delegation is analogous to inheritance, allowing behavioral reuse without changing evaluation context, forwarding is analogous to composition, as execution depends only on the receiving object, not the sending object. In both cases, reuse is dynamic, meaning determined at run time, rather than static, meaning determined at compile/link time. Like inheritance, delegation allows the sending object to modify the original behavior, but is susceptible to problems analogous to the fragile base class; while forwarding provides stronger encapsulation and avoids these problems; see composition over inheritance.

Examples

A simple example of explicit forwarding in Java: an instance of B forwards calls to the foo method of its a field:

class B

Note that when executing a.foo, the this object is a, not the original object. Further, a need not be an instance of A: it may be an instance of a subtype. Indeed, A need not even be a class: it may be an interface/protocol.
Contrast with inheritance, in which foo is defined in a superclass A, and when called on an instance of a subclass B, it uses the code defined in A, but the this object is still an instance of B:

class A
class B extends A

In this Python example, class B forwards the foo method and the x property to the object in its a field: using these on b is the same as using them on b.a.

class A:
def __init__ -> None:
self.x = x
def foo:
print
class B:
def __init__ -> None:
self.a = a
def foo:
self.a.foo
@property
def x:
return self.a.x
@x.setter
def x:
self.a.x = x
@x.deleter
def x:
del self.a.x
a = A
b = B
b.foo # Prints '42'.
b.x # Has value '42'
b.x = 17 # b.a.x now has value 17
del b.x # Deletes b.a.x.

Simple

In this Java example, the class has a method. This print method, rather than performing the print itself, forwards to an object of class. To the outside world it appears that the object is doing the print, but the object is the one actually doing the work.
Forwarding is simply passing a duty off to someone/something else. Here is a simple example:

class RealPrinter
class Printer
public class Main

Complex

The more complex case is a Decorator Pattern that by using interfaces, forwarding can be made more flexible and typesafe. "Flexibility" here means that need not refer to or in any way, as the switching of forwarding is abstracted from. In this example, class can forward to any class that implements an interface. Class has a method to switch to another forwarder. Including the clauses improves type safety, because each class must implement the methods in the interface. The main tradeoff is more code.

interface I
class A implements I
class B implements I
// changing the implementing object in run-time
class C implements I
public class Main

Applications

Forwarding is used in many design patterns. Forwarding is used directly in several patterns:
Forwarding may be used in other patterns, but often use is modified; for example, a method call on one object results in several different methods being called on another: