목차 돌아가기

목차

    퍼사드(Facade)란?

    • 퍼사드 : 건물의 입구쪽 전경이라는 뜻으로 외벽에선 안이 어떻게 생겼는지 알 수없다는 의미

    퍼사드(Facade) 패턴

    복잡한 서브 시스템 의존성을 최소화하는 방법

    클라이언트가 사용해야 하는 복잡한 서브 시스템 의존성을 간단한 인터페이스로 추상화 할 수 있다.

    레거시 코드

    package com.patten.degine_patten.facade._01_before;
    
    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;
    
    /**
     * 실제로 동작하지 않는 코드
     * 가장 간단한 이메일을 보내는 소스 코드
     * 특정한 자바가 제공하는 라이브러리에 의존성이 많은 코드 : SOLID 등 자바가 지향하는 것과 다른 느낌
     */
    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();
            }
        }
    }

    해당 코드에서 java로 이메일을 보내는 코드를 작성한 것이다. 하지만 해당 코드는 너무 javax.mail 이라는 인터페이스에 의존적이다. 

    퍼사드 패턴 적용 추상화 고민하기

    • 메일을 보내는(sender) 클래스
    • 메일 설정
    • 메일 메시지

    이메일을 보내는(sender)

    센더가 의존을 담당한다. (이게 뭐하는 거지..? 조삼모사 아니냐?) 아니다. 의미가 있다. send하는 기능이 여러 곳에서 한다? 약간 util 성으로 의미가 생기게된다.

    package com.patten.degine_patten.facade._02_after;
    
    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", host);
            properties.setProperty("mail.smtp.host", emailSettings.getHost()); //host정보는 setting에
    
            Session session = Session.getDefaultInstance(properties);
    
            try {
                MimeMessage message = new MimeMessage(session);
                //message.setFrom(new InternetAddress(from));
                message.setFrom(new InternetAddress(emailMessage.getFrom())); //from 정보는 메시지에
                //message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
                message.addRecipient(Message.RecipientType.TO, new InternetAddress(emailMessage.getTo())); //to 정보는 메시지에
                message.addRecipient(Message.RecipientType.CC, new InternetAddress(emailMessage.getCc()));
                message.setSubject(emailMessage.getSubject());
                //message.setText("message");
                message.setText(emailMessage.getText());
    
                Transport.send(message);
            } catch (MessagingException e) {
                e.printStackTrace();
            }
        }
    
    
    }

    이메일 메시지

    가장 많은 부분을 담당하는데 이메일에 필요한 내용과 관련된 정보를 담당한다.

    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;
        }
    }

    이메일 설정

    host같은 기본 이메일 설정을 담당한다.

    public class EmailSettings {
    
        private String host;
    
        public String getHost() {
            return host;
        }
    
        public void setHost(String host) {
            this.host = host;
        }
    }

    이메일 메인

    기존과 변화를 살펴보면 메인에서 import 했던 부분들이 사라졌다. 바로 import를 안하지만, 퍼사드에 의존하게 된다.

    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) 패턴의 장점과 단점

    복잡한 서브 시스템 의존성을 최소화하는 방법

    장점

    서브 시스템에 대한 의존성을 한곳으로 모을 수 있다. 결국 코드 읽는게 더 편해지는 것이다. 즉 추상화 정도가 강해진다.

    또한 진입 장벽이 낮다.

    단점

    퍼사드 클래스가 서브 시스템에 대한 모든 의존성을 가지게 된다.

     

    퍼사드 패턴 예제 - Spring

    패턴이 적용 되었다는 것은 보는 각도에 따라 다르게 보일 수 있다. 해당 예제는 브릿지패턴의 예제랑 같지만 보는 각도에 따라 퍼사드라고 볼 수 있다.

    package com.patten.degine_patten.facade._03_java;
    
    import org.springframework.jdbc.support.JdbcTransactionManager;
    import org.springframework.mail.MailSender;
    import org.springframework.mail.javamail.JavaMailSenderImpl;
    import org.springframework.transaction.PlatformTransactionManager;
    
    public class FacadeInSpring {
    
        public static void main(String[] args) {
            MailSender mailSender = new JavaMailSenderImpl();
    
            PlatformTransactionManager platformTransactionManager = new JdbcTransactionManager();
        }
    }

     

    'Java > *****디자인패턴' 카테고리의 다른 글

    [싱글톤 패턴] Spring에서 싱글톤을 사용하는 이유  (0) 2022.05.05
    빌더 패턴  (0) 2022.04.01
    싱글톤 (Singleton) 패턴  (0) 2022.04.01
    디자인 패턴  (0) 2022.03.31
    디자인 패턴 싱글톤 패턴 개념 정리  (0) 2022.03.18

    + Recent posts