Java
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Object-Oriented Java
-
Section 4: Collections Framework
-
Section 5: Exception Handling
-
Section 6: Generics
-
Section 7: Functional Java
-
Section 8: Concurrency
-
Section 9: I/O and NIO
-
Section 10: JVM Internals
-
Section 11: Modern Java Features
-
Section 12: Build Tools and Project Structure
-
Section 13: Testing
-
Section 14: Databases and Persistence
-
Section 15: Networking
-
Section 16: Design and Best Practices
-
Section 17: Reflection and Annotations
-
Section 18: Logging and Diagnostics
-
Section 19: Date, Time, and Internationalization
-
Section 20: Java Platform Module System
-
Section 21: Security in Java
-
Section 22: Advanced Collections and Data Structures
-
Section 23: More Concurrency Patterns
-
Section 24: Compression, Files, and System Integration
-
Section 25: GUI Programming
-
Section 26: Practical Projects
-
Section 27: Data Structures and Algorithms
-
Section 28: Interview and Algorithm Practice
-
Section 29: JSON and Data Interchange
-
Section 30: More Concurrency Utilities
-
Section 31: More Collections and Streams Practice
-
Section 32: More File and System Programming
-
Section 33: Standard Library Deep Dive
-
Section 34: More Practice and Drills
-
Section 35: More Testing and Quality
-
Section 36: More Design Patterns and Architecture
-
Section 37: Career and Ecosystem
-
Section 38: More OOP and Architecture Practice
-
Section 39: More Enterprise Concepts
-
Section 40: Advanced JavaFX
-
Section 41: More Interview Practice
154: The Facade Pattern
I see this a lot when I'm reviewing code from junior developers: they'll build a class that wraps another class and tell me they've implemented the Facade pattern. When I look closer, they've actually just built an Adapter. It's a common point of confusion because both patterns involve creating a wrapper class. But if you mistake one for the other, you'll end up over-engineering your interfaces without actually solving the problem of complexity.
"Wait, Isn't This Just an Adapter?"
The misconception is that a Facade is simply about changing an interface to make it "fit" somewhere else. If you have a LegacySystem class with a method called execute_query_v1() and you create a wrapper that calls it via a method called fetchData(), you haven't built a Facade. You've built an Adapter. You're just translating one language to another.
A Facade isn't about translation; it's about simplification. It's designed to provide a single, simple entry point to a complex subsystem of many classes. If your "Facade" only wraps one other class, you're probably just adding an unnecessary layer of redirection.
Simplifying Complexity, Not Just Changing Interfaces
Think about a home theater. To watch a movie, you don't just "press play." In reality, you have to dim the lights, lower the motorized screen, turn on the projector, set the projector to the right input, turn on the amplifier, set the volume, and finally start the Blu-ray player. Each of these is a separate device (a separate class in our code) with its own API.
Without a Facade, your client code (the person wanting to watch the movie) looks like this:
// This is a nightmare to maintain
Lights lights = new Lights();
Screen screen = new Screen();
Projector projector = new Projector();
Amp amp = new Amp();
BluRayPlayer player = new BluRayPlayer();
lights.dim(10);
screen.down();
projector.on();
projector.setInput("BluRay");
amp.on();
amp.setVolume(20);
player.play("The Matrix");
I hate seeing this in a codebase because if the Projector class changes its setInput method to require an integer ID instead of a string, you have to hunt down every single place in your app where a movie is started and fix it. It's fragile.
Instead, we build a Facade. This class doesn't replace the subsystems—it just coordinates them. The subsystems still exist and can be used individually if you really need that granular control, but for 90% of your use cases, you just want the "Easy Button."
public class HomeTheaterFacade {
private Lights lights;
private Screen screen;
private Projector projector;
private Amp amp;
private BluRayPlayer player;
public HomeTheaterFacade(Lights l, Screen s, Projector p, Amp a, BluRayPlayer b) {
this.lights = l;
this.screen = s;
this.projector = p;
this.amp = a;
this.player = b;
}
public void watchMovie(String movie) {
System.out.println("Get ready to relax...");
lights.dim(10);
screen.down();
projector.on();
projector.setInput("BluRay");
amp.on();
amp.setVolume(20);
player.play(movie);
}
public void endMovie() {
System.out.println("Shutting down theater...");
lights.on();
screen.up();
projector.off();
amp.off();
player.stop();
}
}
Now, your client code is just theater.watchMovie("The Matrix");. You've decoupled the "intent" (watching a movie) from the "implementation" (the sequence of hardware calls). If you upgrade your projector to a model that doesn't need an input setting, you change one line in the Facade, and the rest of your application never even knows anything changed.
📋 Practical Task
Build a Unified Order Processing Facade
You are working on an e-commerce backend. Currently, to complete a purchase, the OrderService has to manually coordinate three different complex subsystems:
InventorySystem(methods:checkStock(itemId),reserveItem(itemId))PaymentProcessor(methods:validateCard(cardNumber),charge(amount))ShippingCourier(methods:calculateShipping(weight),schedulePickup(address))
Your task is to create an OrderFacade class. This class should provide a single method: placeOrder(String itemId, String cardNumber, String address, double amount).
The placeOrder method must perform these steps in order:
- Check if the item is in stock.
- If in stock, reserve the item.
- Validate the credit card.
- Charge the amount.
- Schedule the shipping pickup.
If any step fails (e.g., checkStock returns false), the method should return false immediately and stop the process. If all steps succeed, return true. Ensure your Facade encapsulates these three subsystems so that the main application doesn't have to deal with them individually.
There are no comments for now.