본문 바로가기
Programming/OOP

[Design Pattern] Facade Pattern, 파사드 패턴

by TinKerBellBass 2022. 5. 16.
728x90
반응형

Facade, 파사드는 프랑스어로 정면, 정면의 벽면 정도로 해석할 수 있는데

건물 외벽에 화려한 영상으로 쇼를 하는 "미디어 파사드"에 쓰는 파사드와 같은 단어이다.

디자인 패턴에서는 입구 정도로 해석하면 되지 않을까.

 

Facade Pattern

비교적 간단한 패턴인 파사드 패턴은 일련의 복잡한 내부 동작들을 하나로 묶어주는 인터페이스를 만드는 패턴이다.

여기서 인터페이스는 자바의 인터페이스가 아니라 무엇인가를 사용하기 위한 수단, 방법이다.

즉 파사드 패턴은 다양한 시스템, 라이브러리, 내부 모듈 등을 구성을 통해 통합해서 기능을 제공하는 것이다.

파사드 클래스는 다양한 객체의 협력을 내부에 감싸서 캡슐화해서 제공하기 때문에

사용하는 객체는 그 내부에서 일어나는 일들을 알지 못한다.

 

Facade Pattern Class Diagram

계정에 관련한 서비스를 제공하는 Account 추상 클래스, 

로깅에 관련한 서비스를 제공하는 Log 인터페이스,

알림에 관련한 서비스를 제공하는 Notification 클래스,

그리고 위 세 서비스를 구성을 통해 통합해서 제공하는 파사드 클래가 Bank 이다.

Bank 클래스는 생성자를 통해 세 서비스의 객체를 주입받으며,

저금 + 로깅 + 알람을 통합한 depositWithLogAndNotifiaction 메서드와

출금 + 로깅 + 알람을 통합한 withdrawWithLogAndNotification 메서드를 제공한다.

 

여기서 다른 패턴을 조금 더 적용시킨다고 하면

Bank 종류에 맞는 Account 구현체를 의존성 주입을 통해 주입받는 전략 패턴을 사용할 수도 있고,

그렇게 만들어진 여러 Bank 구현체들을 팩토리 메서드 패턴으로 생성할 수도 있을 것이다.

디자인 패턴은 한 가지만 사용하라는 제한은 어디에도 없다. 필요에 따라 여러 패턴을 결합해서 사용하면 된다.

전체 소스는 https://github.com/Jongwon-Hyun/design_pattern

 

최소 지식 원칙

Principle of Least Knowledge, 최소 지식 원칙은

하나의 객체가 너무 많은 다른 객체를 알고 있으면 안 되며 최소한의 객체만을 알고 있어야 한다는 것이다.

아래의 잘못된 예를 하나 보면 바로 이해가 될 것이다.

public class Bank {
	private final Account account;
    
    public Bank(Account account) {
    	this.account = account;
    }
    
    public Money getMoney() {
    	var CheckingAccount checkingAccount = account.getCheckingAccount()
    	return checkingAccount.getMoney()
    }
}

public class Account {
	private final CheckingAccount checkingAccount;
    
    public Account(CheckingAccount chekcingAccount) {
    	this.checkingAccount = checkingAccount;
    }

	public CheckingAccount getCheckingAccount() {
    	return checkingAccount;
    }
}

Bank 객체는 Account 객체를 구성으로 가지고 있기 때문에 Account 객체의 메서드를 사용하는 것은 문제가 되지 않으나

getMoney 메서드를 보면 Account 객체를 통해 CheckingAccount 객체를 얻어와 CheckingAccount 의 메서드를 사용하고 있다.

Bank 객체가 몰라도 되는 CheckingAccount 객체를 Bank 객체가 알게 된 것이다.

파사드 패턴에서 가끔 이런 실수를 하게 되는데, 최소 지식 원칙에 따라서 리팩터링 하면 다음과 같다.

public class Bank {
	private final Account account;
    
    public Bank(Account account) {
    	this.account = account;
    }
    
    public Money getMoney() {
    	return account.getMoney()
    }
}

public class Account {
	private final CheckingAccount checkingAccount;
    
    public Account(CheckingAccount chekcingAccount) {
    	this.checkingAccount = checkingAccount;
    }

	public Money getMoney() {
    	return checkingAccount.getMoney()
    }
}

 

728x90
반응형

댓글