# 퍼사드 (Facade) 패턴

# 퍼사드 패턴이란 무엇인가요?

Facade는 "건물의 정면"을 의미하는 단어로 어떤 소프트웨어의 다른 커다란 코드 부분에 대하여 간략화된 인터페이스를 제공해주는 디자인 패턴을 의미한다. 퍼사드 객체는 복잡한 소프트웨어 바깥쪽의 코드가 라이브러리의 안쪽 코드에 의존하는 일을 감소시켜 주고, 복잡한 소프트웨어를 사용 할 수 있게 간단한 인터페이스를 제공한다.

image

# 어떤 상황에 사용해야 할까요?

import javax.mail.*;
import java.util.Properties;

public class Client {
    public static void main(String[] args) {
        String to = "songe08@gmail.com";
        String from = "songe08@navedr.com";
        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("Hello World");
            message.setText("Hello World!!!!!");

            Transport.send(message);
        } catch (MessagingException ignored) {}
    }
}

해당 코드는 프로퍼티즈를 이용하여 세션을 만든 뒤, 메세지를 만들어 전송하는 예시이다.

  • 위의 코드에서 다양한 의존성들을 발생하는데, 특정 라이브러리에 의존하는 코드를 최대한 지양해야 한다.
  • 왜냐하면 개발자가 직접 짠 코드에만 집중하기에 효율적이고, 무엇보다 유연하게 의존성을 구성할 수 있기 때문이다.

# 퍼사드 패턴 적용 코드

위의 예시를 역할에 따라 세가지로 분류 할 수 있다.

@Getter
@Setter
public class EmailMessage {
    private String from;
    private String to;
    private String cc;
    private String bcc;
    private String subject;
    private String text;
}
@Getter
@Setter
public class EmailSettings {
    private String host;
}
import javax.mail.*;
import java.util.Properties;

@AllArgsConstructor
public class EmailSender {
    private EmailSettings emailSettings;

    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 ignored) {}
    }
}
  • EmailMessage, EmailSettings, EmailSender 로 나누게 되면 사용측에서 해당 의존성의 깊은 이해에 대한 필요성을 감소시키고, 손쉬운 사용을 제공할 수 있다.
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("moosong");
        emailMessage.setTo("kate");
        emailMessage.setCc("songsong");
        emailMessage.setSubject("Hello World");
        emailMessage.setText("Hello World!!");

        emailSender.sendEmail(emailMessage);
    }
}
  • 위와 같이 코드를 재구성 함으로써, MockUp이 가능해진다.
  • 단순하게 클라이언트 측에서의 사용이 숨겨진다라고만 볼 수 있겠지만, 해당 작업을 여러곳에서 수행할 경우 코드의 중복을 최소화 할 수 있는 이점이 있으며, 인터페이스로 구현한다면, 다른 구현체로 변경할 수 있기에 유연한 코드가 될 수 있다.

# 퍼사드 패턴의 장점은 무엇인가요?

  • 하위 시스템에 대한 의존성을 한 곳으로 모을 수 있다.
  • 가독성 향상 및 리펙토링의 일환으로 볼 수 있다.
  • 추상화를 통해, 라이브러리의 깊은 이해에 대한 필요성을 감소시킬 수 있다.

# 퍼사드 패턴의 단점은 무엇인가요?

  • 퍼사드 클래스가 서브 시스템에 대한 모든 의존성을 가지게 된다.
  • 즉, 의존성을 결국 피할 수는 없다.

# 퍼사드 패턴의 예시는 무엇인가요?

  • 특정 기술에 특화되어 있는 것을 숨기고 인터페이스를 제공하면 퍼사드로 볼 수 있는데,
  • 이때 Spring MVC 에서의 대부분의 기술 독립적인 인터페이스와 구현체가 퍼사드 패턴의 예시가 된다.

# 참고자료

출처 : https://lktprogrammer.tistory.com/42 [맛있는 프로그래머의 일상]
출처: https://www.inflearn.com/course/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4 [GOF 디자인패턴]