ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 퍼사드 패턴 (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 클래스를 통해 서브클래스를 사용할지, 서브클래스를 직접 사용할지 선택 가능하다.

    단점

    • 퍼사드 자체가 서브시스템에 대한 의존성을 가지게 되어 의존성을 피할 수는 없다

     

     

     

    참고


     

    코딩으로 학습하는 GoF의 디자인 패턴 - 인프런 | 강의

    디자인 패턴을 알고 있다면 스프링 뿐 아니라 여러 다양한 기술 및 프로그래밍 언어도 보다 쉽게 학습할 수 있습니다. 또한, 보다 유연하고 재사용성이 뛰어난 객체 지향 소프트웨어를 개발할

    www.inflearn.com

     

Designed by Tistory.