-
퍼사드 패턴 (Facade Pattern)디자인 패턴 2022. 7. 19. 22:08
퍼사드 패턴 (Facade Pattern)
퍼사드 패턴은 복잡한 서브 시스템 의존성을 최소화 하는 방법이다.
클라이언트가 사용해야 하는 복잡한 서브 시스템 의존성을 간단한 인터페이스로 추상화 할 수 있다.
클라이언트가 서브 시스템 클래스나 메서드를 직접 사용하는 것이 아니라 중간에서 복잡한 서브 시스템을 감추고 우리가 사용하는 기능에 대해서만 인터페이스 또는 클래스로 압축시켜 사용하게 해준다.
[참고]
퍼사드란 원래 건물의 입구 쪽을 바라보는 건물의 전경 이라는 뜻이며, 건물의 외벽을 본다고 건물의 안이 어떤지는 알 수 없다.
퍼사드 패턴 적용 전
자바는 이메일 관련 라이브러리가 제공되는데, 클라이언트가 라이브러리에 대해 지나치게 많이 알아야 한다 라는 문제가 발생한다. 아래와 같이 클라이언트가 많은것을 설정하게되면 의존성이 많은 코드가 된다.
Client
import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import java.util.Properties; public class Client { public static void main(String[] args) { String to = "keesun@whiteship.me"; 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(); } } }
위 코드를 살펴보면 라이브러리와 의존성이 단단하게 구현되어있다.
우리는 loosley coupled 한 코드를 만들어, 복잡한 서브시스템을 직접적으로 사용하지 않도록 해주고 싶은것이다.
퍼사드 패턴 적용 후
위 Client 가 설정하고 있는 값들을 각 역할별로 나눠보자.
EmailSetting
public class EmailSettings { private String host; public String getHost() { return host; } public void setHost(String host) { this.host = host; } }
EmailSender
import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import java.util.Properties; public class EmailSender { private EmailSettings emailSettings; public EmailSender(EmailSettings emailSettings) { this.emailSettings = emailSettings; } /** * 이메일 보내는 메소드 * @param emailMessage */ public void sendEmail(EmailMessage emailMessage) { Properties properties = System.getProperties(); properties.setProperty("mail.smtp.host", emailSettings.getHost()); Session session = Session.getDefaultInstance(properties); try { MimeMessage message = new MimeMessage(session); message.setFrom(new InternetAddress(emailMessage.getFrom())); message.addRecipient(Message.RecipientType.TO, new InternetAddress(emailMessage.getTo())); message.addRecipient(Message.RecipientType.CC, new InternetAddress(emailMessage.getCc())); message.setSubject(emailMessage.getSubject()); message.setText(emailMessage.getText()); Transport.send(message); } catch (MessagingException e) { e.printStackTrace(); } } }
EmailMessage
public class EmailMessage { private String from; private String to; private String cc; private String bcc; private String subject; private String text; public String getFrom() { return from; } public void setFrom(String from) { this.from = from; } public String getTo() { return to; } public void setTo(String to) { this.to = to; } public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } public String getText() { return text; } public void setText(String text) { this.text = text; } public String getCc() { return cc; } public void setCc(String cc) { this.cc = cc; } public String getBcc() { return bcc; } public void setBcc(String bcc) { this.bcc = bcc; } }
Client
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 = new EmailMessage(); emailMessage.setFrom("keesun"); emailMessage.setTo("whiteship"); emailMessage.setCc("일남"); emailMessage.setSubject("오징어게임"); emailMessage.setText("밖은 더 지옥이더라고.."); emailSender.sendEmail(emailMessage); } }
Facade 부분에 대한 의존성은 어쩔 수 없지만 직접적으로 라이브러리를 호출하지 않아 이에 대한 의존성이 낮아지고, 테스트하기 더 쉬운 코드가 되었다.
(이전 코드는 Client 가 직접적으로 다양한 라이브러리를 호출하였고 static 메서드를 많이 사용하였기에 테스트가 어려웠다.)
장점과 단점
장점
- 서브 시스템에 대한 의존성을 한곳으로 모을 수 있다.
- 낮은 결합도 : 클라이언트가 서브시스템의 코드를 모르더라도 Facade 클래스를 통해 사용 가능하다.
- 서브 클래스 직접 접근 가능 : Facade 클래스를 통해 서브클래스를 사용할지, 서브클래스를 직접 사용할지 선택 가능하다.
단점
- 퍼사드 자체가 서브시스템에 대한 의존성을 가지게 되어 의존성을 피할 수는 없다
참고
'디자인 패턴' 카테고리의 다른 글
프록시 패턴 (Proxy Pattern) (0) 2022.07.22 플라이웨이트 패턴 (Flyweight Pattern) (0) 2022.07.22 데코레이터 패턴(Decorator Pattern) (0) 2022.07.19 컴포짓 패턴 (Composite Pattern) (0) 2022.07.12 브릿지 패턴 (Bridge Pattern) (0) 2022.07.12