Design Pattern

[디자인 패턴] 퍼사드 패턴 (Facade Pattern)

꾸준함. 2024. 6. 29. 14:07

퍼사드 패턴

  • 퍼사드 패턴은 클라이언트가 사용해야 하는 복잡한 서브 시스템 의존성을 간단한 인터페이스로 추상화하는 데 사용
  • 한 인터페이스로 구성된 높은 수준의 인터페이스를 제공하여 서브시스템을 사용자가 더 쉽게 사용 가능하도록 지원
  • 퍼사드 패턴 적용 시 여러 객체로 구성된 복잡한 서브시스템에 접근할 때 단일 인터페이스를 통해 접근할 수 있게 되어 코드의 가독성 및 유지보수성 향상

 

* Facade는 불어로 `건물의 입구 쪽 전경`을 의미

  • 건물의 전경을 봐서는 내부적으로 배관이 어떻게 설치되어있고 기둥이 어떤 방식으로 설치되었는지 모름

 

https://www.geeksforgeeks.org/facade-design-pattern-introduction/

 

주요 구성 요소

 

1. Facacde

  • 복잡한 서브시스템의 간단한 인터페이스를 제공

 

2. Subsystem

  • 퍼사드가 호출하는 클래스들이며, 복잡한 로직을 포함
  • 퍼사드 객체가 이들 객체의 기능을 조정

 

퍼사드 패턴 구현 예시

  • jakarta.mail 라이브러리를 사용하여 이메일을 보내기 위한 퍼사드 패턴 예시 코드

 

1. SmtpServer (SMTP 서버 설정 클래스)


class SmtpServer {
private Properties properties;
private Session session;
public SmtpServer(String host, String port, final String username, final String password) {
properties = new Properties();
properties.put("mail.smtp.auth", "true");
properties.put("mail.smtp.starttls.enable", "true");
properties.put("mail.smtp.host", host);
properties.put("mail.smtp.port", port);
properties.put("mail.smtp.ssl.trust", host);
session = Session.getInstance(properties, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
}
public Session getSession() {
return session;
}
}
view raw .java hosted with ❤ by GitHub

 

2. EmailMessage (이메일 메시지 생성 클래스)


class EmailMessage {
private MimeMessage message;
public EmailMessage(Session session, String from, String to, String subject, String body) throws
MessagingException {
message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
message.setSubject(subject);
message.setText(body);
}
public MimeMessage getMessage() {
return message;
}
}
view raw .java hosted with ❤ by GitHub

 

3. EmailSender (이메일 전송 클래스)


class EmailSender {
public void sendEmail(MimeMessage message) throws MessagingException {
Transport.send(message);
}
}
view raw .java hosted with ❤ by GitHub

 

4. EmailFacade (파사드 클래스)

 

@Slf4j
class EmailFacade {
private SmtpServer smtpServer;
private EmailSender emailSender;
public EmailFacade(String host, String port, String username, String password) {
smtpServer = new SmtpServer(host, port, username, password);
emailSender = new EmailSender();
}
public void sendEmail(String from, String to, String subject, String body) {
try {
Session session = smtpServer.getSession();
EmailMessage emailMessage = new EmailMessage(session, from, to, subject, body);
emailSender.sendEmail(emailMessage.getMessage());
log.info("Email sent successfully.");
} catch (MessagingException e) {
log.error("Failed to send email.");
}
}
}
view raw .java hosted with ❤ by GitHub

 

5. 클라이언트 코드


public class Client {
public static void main(String[] args) {
String host = "<host>";
String port = "<port>>";
String username = "<username>";
String password = "<password>";
// 이메일 정보
String from = "<your-email>";
String to = "<recipient-email>";
String subject = "파사드 패턴 테스트";
String body = "테스트 이메일";
EmailFacade emailFacade = new EmailFacade(host, port, username, password);
emailFacade.sendEmail(from, to, subject, body);
}
}
view raw .java hosted with ❤ by GitHub

 

부연 설명

  • EmailFacade 클래스는 SMTP 서버 설정, 이메일 메시지 생성, 그리고 이메일 전송 과정을 단순화하여 클라이언트가 쉽게 사용할 수 있도록 지원
  • 클라이언트는 이메일을 보내기 위해 복잡한 세부 사항을 알 필요 없이 EmailFacade를 통해 간단히 이메일을 보낼 수 있음

 

파사드 패턴 장단점

 

장점

  • 복잡한 시스템을 단순한 인터페이스로 감싸서 사용자가 쉽게 사용할 수 있도록 지원하여 가독성 향상
  • 서브시스템과 클라이언트 코드 간의 겹합을 줄임
  • 시스템의 복잡성을 줄이고 유지보수성을 높임

 

단점

  • 퍼사드 클래스 자체가 추가적인 계층이 되어 모든 요청이 퍼사드를 통해 이루어지므로 퍼사드 클래스가 서브시스템에 대한 모든 의존성을 가지게 됨
  • 어찌되었건 추가적인 코드가 늘어나는 것이기 때문에 유지보수 측면에서 공수가 더 많이 들어감

 

실무에서 쓰이는 퍼사드 패턴

 

1. Spring MVC

  • 스프링 프레임워크에서 퍼사드 패턴을 사용하는 예시는 주로 서비스 계층에서 나타남
    • 서비스 계층은 여러 DAO 또는 레포지토리와 상호 작용하여 비즈니스 로직을 처리하고 이를 컨트롤러에게 노출하는 역할
    • 퍼사드 패턴을 사용하면 이러한 비즈니스 로직을 캡슐화하고, 복잡한 내부 동작을 단순화된 인터페이스로 제공

 

2. Spring Framework PlatformTransactionManager

  • 스프링 프레임워크에서 트랜잭션 관리는 JDBC, JPA, Hibernate, JTA 등 다양한 기술과 관련 있으며 각각의 기술은 고유의 트랜잭션 관리 방법을 가지고 있기 때문에 이들을 직접 사용하면 코드가 복잡해짐
  • PlatformTransactionManager는 이러한 다양한 트랜잭션 관리 방법들을 단일 인터페이스로 감싸서 제공함으로써, 개발자가 더 쉽게 트랜잭션을 관리할 수 있도록 지원
  • PlatformTransactionManager는 다음과 같은 메서드를 통해 트랜잭션 관리 기능을 제공
    • TransactionStatus getTransaction(TransactionDefinition definition): 새로운 트랜잭션을 시작하거나, 기존 트랜잭션을 가져옴
    • void commit(TransactionStatus status): 주어진 트랜잭션을 커밋
    • void rollback(TransactionStatus status): 주어진 트랜잭션을 롤백

 

  • 스프링은 여러 가지 PlatformTransactionManager 구현체를 제공
    • DataSourceTransactionManager: JDBC를 사용한 트랜잭션 관리
    • JpaTransactionManager: JPA를 사용한 트랜잭션 관리
    • HibernateTransactionManager: Hibernate를 사용한 트랜잭션 관리
    • JtaTransactionManager: JTA를 사용한 분산 트랜잭션 관리

 

  • 각 구현체는 각각의 기술에 맞는 트랜잭션 관리 로직을 내부적으로 처리하지만, 클라이언트 코드에서는 PlatformTransactionManager 인터페이스를 통해 일관된 방식으로 트랜잭션을 관리 가능

 

참고

코딩으로 학습하는 GoF의 디자인 패턴 - 백기선 강사님

반응형