Bridge Design Pattern


What is Bridge design pattern?

The Bridge Design Pattern is used when there is one set of classes (abstraction) that define features and another set of classes (implementation) that provide the implementation for that features. You then ‘add’ a bridge by injecting the base of the implementation hierarchy to the base of the abstraction hierarchy. To get a more meaningful insight into the definition, imagine that you have an interface that defines some functionality. You will then implement that interface and create an implementation. Now consider that you want to add some more methods to the interface but you do not want all the classes to implement the new methods. What would you do? As a separate case, what if you want a class that just needs to implement one of the methods of the interface and ignore the others? Its cases such as these that are the ideal candidates for the bridge design pattern. The main actors of the pattern are

  • Abstraction

    -This class is the base of the abstraction hierarchy.

  • Refined Abstraction

    -These are the other classes of the abstraction hierarchy that extend the functionalities provided by the “Abstraction” class/interface.

  • Implementor

    -This is the base of the implementation hierarchy. The “Abstraction” class would hold a reference to this class/interface (hence the bridge). The methods for Implementor and Abstraction class could be different and the Implementor class generally holds methods that provide more fine grained functionalities.

  • Implementor

    -These are other classes of the implementation hierarchy

Bridge Design Pattern Example

To Demonstrate the bridge design pattern let us look at an example – Let’s say there is a Computer manufacturing company that wants to write a system for calculating the prices of their products. The prices depend on the base price and additional customs and excise, if any. The levy of the additional taxes depends on the country. We have two hierarchies here, the “abstraction” hierarchy includes the base pricing class and the derived customs and excise pricing classes. The “Implementation” hierarchy consists of a base implementation class and the country pricing classes extend this base class. Here’s the class diagram

Bridge Design Pattern Example

package com.studytrails.patterns.bridge;

/**
 *
 * The top class of the abstraction hierarchy. This class has a reference to the
 * actual implementation and hence stores the 'bridge'. It defines methods that
 * delegate behaviour to the actual implementation class.
 *
 */
public class ComputerPricing {
	ComputerPricingImpl computerPricingImpl;

	public double getPrice() {
		return computerPricingImpl.getBaseRate() + computerPricingImpl.getShippingRate();

	}

	public double getExcise() {
		return computerPricingImpl.getExciseRate();
	}

	public double getCustoms() {
		return computerPricingImpl.getCustomsRate();
	}
}

					

package com.studytrails.patterns.bridge;

/**
 * The top of the implementation hierarchy. The concrete classes would implement
 * the base rate, shipping rate, excise rate and customs rate.
 *
 */
public abstract class ComputerPricingImpl {
	public abstract double getBaseRate();

	public abstract double getShippingRate();

	public abstract double getExciseRate();

	public abstract double getCustomsRate();

}

					

package com.studytrails.patterns.bridge;

/**
 * This is an implementation class for AU. It determines the pricing model for
 * AU and also calculates the excise and customs. Note that it might delegate
 * actual processing to other private methods such as calculateCustoms.
 *
 */
public class ComputerPricingImplAU extends ComputerPricingImpl {
	@Override
	public double getBaseRate() {
		return 1000;
	}

	@Override
	public double getCustomsRate() {
		return calculateCustoms();
	}

	@Override
	public double getExciseRate() {
		return 0;
	}

	@Override
	public double getShippingRate() {
		return 3;
	}

	private double calculateCustoms() {
		return 9;
	}
}

					

package com.studytrails.patterns.bridge;

/**
 * This is an implementation class for US. It determines the pricing model for
 * US and also calculates the excise and customs. Note that it might delegate
 * actual processing to other private methods such as calculateExcise.
 *
 */
public class ComputerPricingImplUS extends ComputerPricingImpl {
	@Override
	public double getBaseRate() {
		return 1000;
	}

	@Override
	public double getCustomsRate() {
		return 0;
	}

	@Override
	public double getExciseRate() {
		return calculateExcise();
	}

	@Override
	public double getShippingRate() {
		return 3;
	}

	private double calculateExcise() {
		return 11;
	}
}

					

package com.studytrails.patterns.bridge;

/**
 * We need a quote for a price of a computer with applicable Customs duty.
 */
public class ComputerPricingWithCustoms extends ComputerPricing {
	@Override
	public double getPrice() {
		return getPrice() + getCustoms();
	}
}

					

package com.studytrails.patterns.bridge;

/**
 * We need a quote for a price of a computer with applicable excise duty.
 */
public class ComputerPricingWithExcise extends ComputerPricing {

	/**
	 * This would delegate to the parent class which just uses the behaviour
	 * from the implementation class.
	 */
	public double getPrice() {
		return getPrice() + getExcise();
	}

}
}
}

					

Bridge Design pattern reduces an explosion of classes by dividing the abstraction and implementation into two separate hierarchies.

There is no point using the bridge design pattern if there is only a single implementation class.

The exact implementation is determined at run time and different implementations can be plugged in at different times.

This finishes our tutorial on the bridge design pattern. remember bridge design pattern is the separation of implementation hierarchy from abstraction hierarchy.

Leave a Comment