Generic Top

I just announced the new Spring Boot 2 material, coming in REST With Spring:


1. Introduction

In this article, we’re going to focus on Structural Design Patterns in Java – and discuss what these are and some fundamental differences between some of them.

2. Structural Design Patterns

According to the Gang Of Four (GoF), design patterns can be classified into three types:

  1. Creational
  2. Structural
  3. Behavioural

Simply put, Structural Patterns deal with the composition of classes and objects. They provide different ways of using object composition and inheritance to create some abstraction.

3. Proxy Pattern

With this pattern, we create an intermediary that acts as an interface to another resource, e.g., a file, a connection. This secondary access provides a surrogate for the real component and protects it from the underlying complexity.

3.1. Proxy Pattern Example

Consider a heavy Java object (like a JDBC connection or a SessionFactory) that requires some initial configuration.

We only want such objects to be initialized on demand, and once they are, we’d want to reuse them for all calls:

Let’s now create a simple interface and the configuration for this object:

public interface ExpensiveObject {
    void process();

And the implementation of this interface with a large initial configuration:

public class ExpensiveObjectImpl implements ExpensiveObject {

    public ExpensiveObjectImpl() {
    public void process() {"processing complete.");
    private void heavyInitialConfiguration() {"Loading initial configuration...");

We’ll now utilize the Proxy pattern and initialize our object on demand:

public class ExpensiveObjectProxy implements ExpensiveObject {
    private static ExpensiveObject object;

    public void process() {
        if (object == null) {
            object = new ExpensiveObjectImpl();

Whenever our client calls the process() method, they’ll just get to see the processing and the initial configuration will always remain hidden:

public static void main(String[] args) {
    ExpensiveObject object = new ExpensiveObjectProxy();

Note that we’re calling the process() method twice. Behind the scenes, the settings part will occur only once – when the object is first initialized.

For every other subsequent call, this pattern will skip the initial configuration, and only processing will occur:

Loading initial configuration...
processing complete.
processing complete.

3.2. When to Use Proxy

Understanding how to use a pattern is important.

Understanding when to use it is critical.

Let’s talk about when to use the Proxy pattern:

  • When we want a simplified version of a complex or heavy object. In this case, we may represent it with a skeleton object which loads the original object on demand, also called as lazy initialization. This is known as the Virtual Proxy
  • When the original object is present in different address space, and we want to represent it locally. We can create a proxy which does all the necessary boilerplate stuff like creating and maintaining the connection, encoding, decoding, etc., while the client accesses it as it was present in their local address space. This is called the Remote Proxy
  • When we want to add a layer of security to the original underlying object to provide controlled access based on access rights of the client. This is called Protection Proxy

3.3. Key Points of Differentiation

  • The proxy provides the same interface as the object it’s holding the reference to, and it doesn’t modify the data in any manner; it’s in contrast to Adapter and Decorator patterns which alter and decorate the functionalities of pre-existing instances respectively
  • The Proxy usually has the information about the real subject at the compile time itself whereas Decorator and Adapter get injected at runtime, knowing only the actual object’s interface

4. Decorator Pattern

This pattern is useful for enhancing the behavior of an object. For a detailed overview, have a look at the focused tutorial here: Decorator Pattern in Java

Key points of differentiation:

  • Although Proxy and Decorator patterns have similar structures, they differ in intention; while Proxy’s prime purpose is to facilitate ease of use or controlled access, a Decorator attaches additional responsibilities
  • Both Proxy and Adapter patterns hold a reference to the original object
  • All the decorators from this pattern can be used recursively, an infinite number of times, which is not possible with other models

5. Adapter Pattern

An Adapter pattern acts as a connector between two incompatible interfaces that otherwise cannot be connected directly. An Adapter wraps an existing class with a new interface so that it becomes compatible with cliethe nt’s interface.

The main motive behind using this pattern is to convert an existing interface into another interface that the client expects. It’s usually implemented once the application is designed.

5.1. Adapter Pattern Example

Consider a scenario in which there is an app that’s developed in the US which returns the top speed of luxury cars in miles per hour (MPH). Now we need to use the same app for our client in the UK that wants the same results but in kilometers per hour (km/h).

To deal with this problem, we’ll create an adapter which will convert the values and give us the desired results:

First, we’ll create the original interface Movable which is supposed to return the speed of some luxury cars in miles per hour:

public interface Movable {
    // returns speed in MPH 
    double getSpeed();

We’ll now create one concrete implementation of this interface:

public class BugattiVeyron implements Movable {
    public double getSpeed() {
        return 268;

Now we’ll create an adapter interface MovableAdapter that will be based on the same Movable class. It may be slightly modified to yield different results in different scenarios:

public interface MovableAdapter {
    // returns speed in KM/H 
    double getSpeed();

The implementation of this interface will consist of private method convertMPHtoKMPH() that will be used for the conversion:

public class MovableAdapterImpl implements MovableAdapter {
    private Movable luxuryCars;
    // standard constructors

    public double getSpeed() {
        return convertMPHtoKMPH(luxuryCars.getSpeed());
    private double convertMPHtoKMPH(double mph) {
        return mph * 1.60934;

Now we’ll only use the methods defined in our Adapter, and we’ll get the converted speeds. In this case, the following assertion will be true:

public void whenConvertingMPHToKMPH_thenSuccessfullyConverted() {
    Movable bugattiVeyron = new BugattiVeyron();
    MovableAdapter bugattiVeyronAdapter = new MovableAdapterImpl(bugattiVeyron);
    assertEquals(bugattiVeyronAdapter.getSpeed(), 431.30312, 0.00001);

As we can notice here, our adapter converts 268 mph to 431 km/h for this particular case.

5.2. When to Use Adapter Pattern

  • When an outside component provides captivating functionality that we’d like to reuse, but it’s incompatible with our current application. A suitable Adapter can be developed to make them compatible with each other
  • When our application is not compatible with the interface that our client is expecting
  • When we want to reuse legacy code in our application without making any modification in the original code

5.3. Key Points of Differentiation

  • While proxy provides the same interface, Adapter provides a different interface that’s compatible with its client
  • Adapter pattern is used after the application components are designed so that we can use them without modifying the source code. This is in contrast to Bridge pattern, which is used before the components are designed.

6. Bridge Pattern

The official definition for Bridge design pattern introduced by Gang of Four (GoF) is to decouple an abstraction from its implementation so that the two can vary independently.

This means to create a bridge interface that uses OOP principles to separate out responsibilities into different abstract classes.

6.1. Bridge Pattern Example

For the Bridge pattern, we’ll consider two layers of abstraction; one is the geometric shape (like triangle and square) which is filled with different colors (our second abstraction layer):

First, we’ll define a color interface:

public interface Color {
    String fill();

Now we’ll create a concrete class for this interface:

public class Blue implements Color {
    public String fill() {
        return "Color is Blue";

Let’s now create an abstract Shape class which consists a reference (bridge) to the Color object:

public abstract class Shape {
    protected Color color;
    //standard constructors
    abstract public String draw();

We’ll now create a concrete class of Shape interface which will utilize method from Color interface as well:

public class Square extends Shape {

    public Square(Color color) {

    public String draw() {
        return "Square drawn. " + color.fill();

For this pattern, the following assertion will be true:

public void whenBridgePatternInvoked_thenConfigSuccess() {
    //a square with red color
    Shape square = new Square(new Red());
    assertEquals(square.draw(), "Square drawn. Color is Red");

Here, we’re using Bridge pattern and passing the desired color object. As we can note in the output, the shape gets draws with the desired color:

Square drawn. Color: Red
Triangle drawn. Color: Blue

6.2. When to Use Bridge Design Pattern

  • When we want a parent abstract class to define the set of basic rules, and the concrete classes to add additional rules
  • When we have an abstract class that has a reference to the objects, and it has abstract methods that will be defined in each of the concrete classes

6.3. Key Points of Differentiation

  • A Bridge pattern can only be implemented before the application is designed.
  • Allows an abstraction and implementation to change independently whereas an Adapter pattern makes it possible for incompatible classes to work together

7. Conclusion

In this article, we focused on the Structural Design Pattern and differences between some of its types.

As always, the full implementation of this tutorial can be found over on Github.

Generic bottom

I just announced the new Spring Boot 2 material, coming in REST With Spring: