Proxy Pattern – Delegating to Multiple Implementations

design-patterns

In a traditional GoF Proxy, you have an Interface, an Implementation, that implements the Interface, and a Proxy that also implements the Interface, references an instance of Implementation, and delegates the calls on the Interface methods to the same methods in the Implementation instance.

Say you would call the Interface/Implementation pair a "Fragment", and you would have several different such pairs. Now imagine you create a Whole Interface that implemented all those Fragment interfaces, and a single Whole Proxy that implemented the Whole Interface, and delegated to the appropriate Fragment Implementation instance.

A code (Java) example:

// Fragment A:
interface FragmentA { ... }
class FragmentAImpl implements FragmentA { ... }
// Whole A. That is the interface that "clients use"
interfaces WholeA extends FragmentA { // EMPTY! }
// *automatically generated* Proxy:
class ProxyA implements WholeA {
    private FragmentA implA;
    // Implements FragmentA through delegation to implA
}

// Fragment B:
interface FragmentB { ... }
class FragmentBImpl implements FragmentB { ... }
// Whole B. That is the interface that "clients use"
interfaces WholeB extends WholeA, FragmentB { // EMPTY! }
// *automatically generated* Proxy:
class ProxyB extends ProxyA implements WholeB {
    private FragmentB implB;
    // Implements FragmentB through delegation to implB
}

// Fragment C: similar to Fragment B, but with different *added behavior*.

Is this pattern at all (since Patterns must be common solution to common problems)? And if so, as it got a name? Or could it be cleanly defined as a combination of patterns?

Being able to clearly describe how this code works in terms of patterns would make it much easier to explain to others how create compatible code, and help to find a framework that already implements this pattern.

A Proxy normally delegates to a single instance.

A Facade normally offers a different interface to that multiple objects it hides.

A Bridge also offers a different interface to that the single instance it hides.

A Composite expects all components to share the same base interface.

A Decorator extends the interface of the wrapped object, like here, but normally implements the additional functionality itself, instead of delegating to another objects.

A Whole that implements a single Fragment is just a Proxy pattern, but a Whole that extends another Whole is closest to a Decorator pattern.

There are several reasons to do it this way. Firstly, client code should see WholeB as extending WholeA, although the implementer of FragmentB cannot extend FragmentA (which was implemented by someone else). Secondly, references to WholeX (ProxyX) stay valid, even if implementation of FragmentX is replaced a runtime. Thirdly, both ProxyB and ProxyC can share the same instance of FragmentAImpl.

Best Answer

I'd still go with facade.

It offers a single port of call for clients needing the services of several interfaces. This is a facade. The fact that normally a facade declares a specific interface instead of re-using the ones from the classes/objects it aggregates is, to me, an implementation detail.

Update

From the GoF book:

Intent: Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystems easier to use.

Especially when you then read

Motivation: Structuring a system into sybsystems helps reduce complexity. A common design goal it to minimize the communication and dependencies between subsysems. One way to achieve this goal is to introduce a facade object that provides a single, simplified interface to the more general facilities of a subsystem.

While the comment by @pdr would seem correct, I would argue differently.

The "simplified" interface can most certainly be the same as the interfaces put behind the facade. Its just a question of how simple those "facaded" interfaces are.

Plus, I don't take "simplifies" as a requirement for an object to be a facade.

The motivation to minimize communication and dependencies between subsystems is far more important and the main goal of the facade pattern. A facade object providing a single point of access to multiple (unchanged interfaces of) subsystems, still fulfills this goal regardless of whether it (also) simplifies the interface(s) offered by the subsystems it hides.

Related Topic