퍼사드(Facade) 패턴
facade 뜻
얼굴, 건물에서는 건물의 얼굴, 즉 주요 전면을 의미한다.
복잡한 서브 시스템 의존성을 최소화하는 방법
클라이언트가 사용해야 하는 복잡한 서브 시스템 의존성을 간단한 인터페이스로 추상화 할 수 있다.
퍼사드(Facade) 패턴 before
public class Client {
public static void main(String[] args) {
String to = "baejeu@naver.com";
String from = "whiteship@whiteship.me";
String host = "127.0.0.1";
Properties properties = System.getProperties();
properties.setProperty("mail.smtp.host", host);
Session session = Session.getDefaultInstance(properties);
try {
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
message.setSubject("Test Mail from Java Program");
message.setText("message");
Transport.send(message);
}
catch (MessagingException e){
e.printStackTrace();
}
}
}
실제 동작하는 코드는 아니다.
현재 클라이언트의 메일 전송 코드는 여러가지 문제점이 있다.
메일을 보내기 위한 다양한 설정과 객체 생성 과정이 클라이언트 코드에 포함되어 있어 가독성이 떨어진다.
클라이언트는 메일 전송의 내부 작동방식을 알아야 한다.
만약 메일 전송 로직이 변경되거나 추가적인 기능이 필요한 경우, 클라이언트 코드 전체를 수정해야 할 수 있다.
이는 코드의 중복과 유지 보수의 어려움을 초래한다.
클라어언트는 jakrata.mail 패키지에 직접 의존하고 있으며, 이는 클라이언트 코드가 이메일 전송의 세부 사항에 강하게 결합되어 있음을 의미한다.
이러한 문제들을 facade 패턴을 적용해서 개선해 보자.
퍼사드(Facade) 패턴 after
@Getter @Setter
public class EmailSettings {
private String host;
}
@Getter @Builder
public class EmailMessage {
private String to;
private String from;
private String subject;
private String text;
}
@RequiredArgsConstructor
public class EmailSender {
private final EmailSettings emailSettings;
public void sentEmail(EmailMessage message){
Properties properties = System.getProperties();
properties.setProperty("mail.smtp.host", emailSettings.getHost());
Session session = Session.getDefaultInstance(properties);
try {
MimeMessage mimeMessage = new MimeMessage(session);
mimeMessage.setFrom(new InternetAddress(message.getFrom()));
mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(message.getTo()));
mimeMessage.setSubject(message.getSubject());
mimeMessage.setText(message.getText());
}
catch (MessagingException e){
e.printStackTrace();
}
}
}
클라이언트 코드
public class Client {
public static void main(String[] args) {
EmailSettings emailSettings = new EmailSettings();
emailSettings.setHost("127.0.0.1");
EmailSender emailSender = new EmailSender(emailSettings);
EmailMessage emailMessage = EmailMessage.builder()
.to("baejeu@naver.com")
.from("whiteship@whiteship.me")
.subject("제목")
.text("내용")
.build();
emailSender.sentEmail(emailMessage);
}
}
before와 비교했을 때 현재 코드는 어떤 장점이 있을까?
먼저 클라이언트 코드를 보면 가독성이 훨씬 더 좋아졌다.
클라이언트가 직접 의존하고 있던 jakarta.email 패키지에 대한 의존이 사라졌다.
의존을 퍼사드인 EmailSender에게 맡겼기 때문이다.
EmailSender는 현재는 클래스지만 인터페이스로 바꾼다면 더욱 유연성이 늘어날 것이다.
인터페이스로 바꾸지 않더라도 테스트를 할 때 모킹(mocking) 또한 가능하다.
이를 통해 유닛 테스트를 쉽게 작성할 수 있어 코드 품질이 향상된다.
이메일 설정(EmailSettings)과 메시지(EmailMessage)를 별도의 클래스로 분리함으로써
이메일 전송이 변경되더라도 클라이언트 코드에는 영향을 주지 않게 되었다.
→ OCP
각각의 클래스가 하나의 책임을 가진다.
이를 통해 유지 보수가 쉬워졌다.
→ SRP
EmailSender와 EmailMessage 클래스는 다른 클라이언트에서도 재사용 가능하므로 코드 중복을 줄일 수 있다.
퍼사드(Facade) 패턴 정리
복잡한 서브 시스템 의존성을 최소화하는 방법
장점
서브 시스템에 대한 의존성을 한곳으로 모을 수 있다.
단점
퍼사드 클래스가 서브 시스템에 대한 모든 의존성을 가지게 된다.
참고자료
'Computer Sience > Desgin Pattern' 카테고리의 다른 글
[Design Pattern] 프록시(Proxy) 패턴 + 다이나믹 프록시 (0) | 2024.10.30 |
---|---|
[Design Pattern] 플라이웨이트(Flyweight) 패턴 (1) | 2024.10.30 |
[Design Pattern] 데코레이터 (Decorator) 패턴 (0) | 2024.10.28 |
[Design Pattern] 컴포짓 (Composite) 패턴 (1) | 2024.10.24 |
[Design Pattern] 브릿지 (Bridge) 패턴 (0) | 2024.10.23 |