Definition
- Facade – provides a single, simplified interface over a complex subsystem of many classes, hiding their interactions so clients deal with one easy entry point.
- Adapter – converts the interface of an existing class into another interface that a client expects, so two incompatible types can work together.
- Intent difference – Facade simplifies and unifies; Adapter translates and bridges.
- Interface design – with Facade you create a new convenient interface; with Adapter you conform to a fixed target interface.
- Trigger – Facade is proactive simplification; Adapter is reactive glue for a discovered mismatch.
A Facade is like the single relationship manager at National Bank of India who handles Rajesh's whole request. Behind her are many departments: accounts, loans, cards, compliance. She gives Rajesh one simple door into a complicated building. An Adapter is different: imagine Rajesh brings a foreign credit-score report in a format the bank's loan software cannot read. The bank uses a small translator that converts that report into the exact format the software expects. The Facade simplifies a building; the Adapter makes one specific thing fit a socket.
Understanding the Concepts
What is the Facade pattern?
Facade is about simplification and decoupling. You have a subsystem of many classes that must be used together in a particular sequence. A Facade is a single class that exposes a small number of high-level methods and orchestrates the subsystem internally.
package com.bank.facade;
import java.math.BigDecimal;
public class AccountOpeningFacade {
private final KycService kyc;
private final AccountRepository repo;
private final CardIssuer cards;
private final NotificationService notifier;
public AccountOpeningFacade(KycService kyc, AccountRepository repo,
CardIssuer cards, NotificationService notifier) {
this.kyc = kyc; this.repo = repo;
this.cards = cards; this.notifier = notifier;
}
public String openAccount(AccountRequest request) {
kyc.verify(request.getPan());
String accountId = repo.create(request);
cards.issueDebitCard(accountId);
notifier.sendWelcome(request.getEmail());
return accountId;
}
}
The client calls one method instead of coordinating four services.
What is the Adapter pattern?
Adapter is about compatibility. You have an existing class whose interface does not match what your code expects. The Adapter sits between them and translates.
package com.bank.adapter;
// Target interface the bank's code expects
public interface CreditScoreProvider {
int getScore(String pan);
}
// Third-party vendor with incompatible interface
public class CibilApi {
public CibilResponse fetch(CibilRequest request) {
// vendor-specific implementation
return new CibilResponse(750);
}
}
// Adapter translates vendor to target
public class CibilAdapter implements CreditScoreProvider {
private final CibilApi api;
public CibilAdapter(CibilApi api) {
this.api = api;
}
@Override
public int getScore(String pan) {
CibilRequest request = new CibilRequest(pan);
CibilResponse response = api.fetch(request);
return response.getScore();
}
}
How do Facade and Adapter differ?
The core difference is intent.
| Aspect | Facade | Adapter |
|---|---|---|
| Intent | Simplify a complex subsystem | Bridge an interface mismatch |
| Number of objects | Fronts many subsystem classes | Wraps a single adaptee |
| Interface design | You design a new convenient interface | Target interface already exists and is fixed |
| When to use | Proactive: subsystem is painful | Reactive: discovered a mismatch |
| Scope | Many services orchestrated | One class translated |
| Client knowledge | Client never knows the subsystem | Client never knows the adaptee |
// Facade: simplifies many things into one call
accountOpeningFacade.openAccount(request);
// Adapter: translates one thing into the expected interface
CreditScoreProvider provider = new CibilAdapter(new CibilApi());
int score = provider.getScore("ABCDE1234F");
When do you use Facade vs Adapter?
Use Facade when a subsystem has many classes that must be used together and the calling code is getting complex. You want one clean entry point. Use Adapter when you must integrate a library, legacy system, or vendor whose interface does not match what your code expects and you cannot or do not want to change it.
// Facade scenario: opening an account requires 4 steps
// Without facade, the controller does this:
kyc.verify(pan);
String id = repo.create(request);
cards.issueDebitCard(id);
notifier.sendWelcome(email);
// With facade, the controller does this:
facade.openAccount(request); // one call
// Adapter scenario: vendor API has different method signature
// Without adapter, your code is coupled to the vendor:
CibilResponse resp = cibilApi.fetch(new CibilRequest(pan));
int score = resp.getScore();
// With adapter, your code uses your own interface:
int score = provider.getScore(pan);
Can Facade and Adapter coexist?
Yes. A Facade can internally use Adapters to talk to incompatible subsystem pieces. This is common in real systems.
package com.bank.facade;
import com.bank.adapter.CibilAdapter;
import com.bank.adapter.CibilApi;
import java.math.BigDecimal;
public class LoanApprovalFacade {
private final CreditScoreProvider scoreProvider; // Adapter
private final LoanRepository loanRepo;
private final NotificationService notifier;
public LoanApprovalFacade() {
// Facade uses an Adapter internally
this.scoreProvider = new CibilAdapter(new CibilApi());
this.loanRepo = new LoanRepository();
this.notifier = new NotificationService();
}
public boolean approveLoan(String pan, BigDecimal amount) {
int score = scoreProvider.getScore(pan); // via Adapter
if (score < 650) return false;
loanRepo.create(pan, amount);
notifier.sendApproval(pan);
return true;
}
}
What are the object adapter and class adapter forms?
An object adapter holds a reference to the adaptee and delegates, which is the common composition-based form. A class adapter uses multiple inheritance (in Java: implementing the target interface while extending the adaptee), which is less flexible.
// Object adapter (preferred): composition
public class CibilAdapter implements CreditScoreProvider {
private final CibilApi api; // holds reference
// ...
}
// Class adapter: inheritance (less flexible)
public class CibilClassAdapter extends CibilApi implements CreditScoreProvider {
@Override
public int getScore(String pan) {
return this.fetch(new CibilRequest(pan)).getScore();
}
}
What are common mistakes?
The most common mistake is confusing Facade with Adapter because both wrap other objects. The quick test: am I simplifying many things into one easy interface (Facade), or am I translating one specific thing into a different expected interface (Adapter)?
// Wrong mental model: "both are wrappers, so they are the same"
// Correct mental model:
// Facade = one simple door to a complex building
// Adapter = one plug converter for one incompatible device
What are real Java examples?
java.util.Arrays.asList adapts an array to the List interface: that is an Adapter. SLF4J bindings adapt one logging API to another: that is an Adapter. A service class that wraps several repositories and clients to offer one business operation is a Facade.
// Adapter: Arrays.asList converts array to List interface
List<String> list = Arrays.asList("HDFC", "ICICI", "SBI");
// Facade: service wraps multiple collaborators
transferFacade.transfer(fromId, toId, amount);
What should a senior engineer know?
A senior engineer recognises that a Facade is proactive simplification planned during design, while an Adapter is often reactive glue to bridge a mismatch discovered during integration. Both are complementary. At National Bank of India, the account-opening flow uses a Facade to orchestrate KYC, account creation, card issuance, and notification, and inside that Facade uses a CibilAdapter to bridge the vendor's credit-score API to the bank's internal CreditScoreProvider interface.
Visual Overview
Facade
──────
Client ──→ AccountOpeningFacade.openAccount()
│
┌─────────┼─────────┬──────────┐
▼ ▼ ▼ ▼
KycService Repo CardIssuer Notifier
Adapter
───────
Client ──→ CreditScoreProvider.getScore(pan)
│
▼
CibilAdapter
│
▼
CibilApi.fetch(request)
(incompatible third-party)
Facade + Adapter together
─────────────────────────
Controller ──→ LoanApprovalFacade.approveLoan()
│
┌──────────┼──────────┐
▼ ▼ ▼
CibilAdapter LoanRepo Notifier
│
▼
CibilApi (vendor)
Key Takeaway
The Facade pattern and the Adapter pattern are both structural patterns that wrap other objects, which is why they are easily confused, but their intent is completely different. A Facade provides a single simplified interface over a complex subsystem of many classes, hiding their interactions so the client deals with one easy entry point. An Adapter converts the interface of an existing class into a different interface that the client expects, so two incompatible types work together.
The cleanest way to distinguish them is by asking one question: am I simplifying many collaborating classes into one convenient interface, or am I translating one specific thing into a different expected interface? If it is simplification over a subsystem, it is a Facade. If it is translation to achieve compatibility, it is an Adapter. A Facade usually fronts many subsystem classes and lets you design a brand-new convenient interface, while an Adapter typically wraps a single adaptee and must conform to a target interface that already exists.
In the banking project at National Bank of India, the account-opening flow uses both. Opening an account requires KYC, saving the account, issuing a card, and sending a welcome message. Rajesh created an AccountOpeningFacade with a single openAccount method that orchestrates all four services. That is a Facade. Inside that flow, the credit-score lookup uses a CibilAdapter that implements the bank's CreditScoreProvider interface and translates calls into the vendor's incompatible API. That is an Adapter. The Facade uses the Adapter internally, showing the patterns are complementary.
A couple of standard Java examples: Arrays.asList adapts an array to the List interface (Adapter), and SLF4J bindings adapt one logging API to another (Adapter), while any service class wrapping repositories and clients to expose one business operation is a Facade.
Remember one sentence: Facade simplifies a complex building into one front door, Adapter makes one incompatible plug fit a different socket.
---