A set of complex subsystems can have a higher-level simplified interface thanks to the structural design pattern known as facade.
Motivation
Interacting with a set of complex classes which includes keeping track of dependencies, initializing objects, and ensuring methods are called in the right order can be cumbersome, error-prone, and can also lead to tight coupling. Instead of letting clients work with these subsystems directly, creating a higher-level interface on top of the complex systems can help simplify the interaction.
Implementation
Imagine building a food ordering library where a lot of things happen under the scenes right from the cart manager adding the food to the cart, and removing the food from the cart to the Cost calculator that helps calculate the cost of the food order, as well as the Money manager class that handles payment by debiting the client. The kitchen Manager gets informed about the food order and starts to prepare the dish, after the food has been prepared the Delivery Manager handles the delivery to the client.
public class FoodOrderService {
public void orderFood(Food food) {
CartManager cartManager = new CartManager();
cartManager.addFoodToCart(food);
CostCalculator costCalculator = new CostCalculator();
costCalculator.calculateCost(food);
MoneyManager moneyManager = new MoneyManager();
moneyManager.debitMoney(food);
KitchenManager kitchenManager = new KitchenManager();
kitchenManager.makeFood(food);
DeliveryManager deliveryManager = new DeliveryManager();
deliveryManager.deliverFood(food);
}
}
public class CartManager {
public void addFoodToCart(Food food) {
System.out.println("Adding Food to cart");
System.out.println("Added to cart Food :" + food);
}
}
public class CostCalculator {
public void calculateCost(Food food) {
System.out.println("Calculating cost of Food:" + food);
}
}
public class MoneyManager {
public void debitMoney(Food food){
System.out.println("Debiting money for Food :" + food );
}
}
public class KitchenManager {
public void makeFood(Food food) {
System.out.println("Preparing the food:" + food);
}
}
public class DeliveryManager {
public void deliverFood(Food food) {
System.out.println("Delivering the food:" + food);
}
}
It is extremely messy to keep track of these processes as a third party or client trying to make use of the library, that is where the facade pattern comes in, it creates a simplified interface where the client interacts with and all the processes are handled under the scene in the right order.
FoodOrderService class simplifies the whole process of ordering food and exposes the orderFood method which makes things simpler for the client.
FoodOrderService foodOrderService = new FoodOrderService();
Food food = new Food("Jollof Rice", 2);
foodOrderService.orderFood(food);
Advantages
- It simplifies the interface for a client
- Reduces dependencies between the client and subsystems
- Helps with abstraction by hiding the intricate nature of the system.
Disadvantages
It can be monolithic if not designed properly.
Conclusion
The Facade Pattern provides a method for hiding a subsystem's intricacies by offering a simplified interface for clients to interact with. It promotes decoupling which helps to make systems easier to manage. While it does its job perfectly when designed properly, it is important for care to be taken to ensure that the facade pattern itself does not become too complex.
Top comments (0)