반응형
Jake Seo
제이크서 위키 블로그
Jake Seo
전체 방문자
오늘
어제
  • 분류 전체보기 (715)
    • 일상, 일기 (0)
    • 백준 문제풀이 (1)
    • 릿코드 문제풀이 (2)
    • 알고리즘 이론 (10)
      • 기본 이론 (2)
      • 배열과 문자열 (8)
    • 데이터베이스 (15)
      • Planet Scale (1)
      • MSSQL (9)
      • 디비 기본 개념 (1)
      • SQLite 직접 만들어보기 (4)
    • 보안 (7)
    • 설계 (1)
    • 네트워크 (17)
      • HTTP (9)
      • OSI Layers (5)
    • 회고 (31)
      • 연간 회고 (2)
      • 주간 회고 (29)
    • 인프라 (52)
      • 도커 (12)
      • AWS (9)
      • 용어 (21)
      • 웹 성능 (1)
      • 대규모 서비스를 지탱하는 기술 (9)
    • 깃 (7)
    • 빌드 도구 (7)
      • 메이븐 (6)
      • 그레이들 (0)
    • Java (135)
      • 이펙티브 자바 (73)
      • 자바 API (4)
      • 자바 잡지식 (30)
      • 자바 디자인 패턴 (21)
      • 톰캣 (Tomcat) (7)
    • 프레임워크 (64)
      • next.js (14)
      • 스프링 프레임워크 (28)
      • 토비의 스프링 (6)
      • 스프링 부트 (3)
      • JPA (Java Persistence API) (5)
      • Nest.js (8)
    • 프론트엔드 (48)
      • 다크모드 (1)
      • 노드 패키지 관리 매니저 (3)
      • CSS (19)
      • Web API (11)
      • tailwind-css (1)
      • React (5)
      • React 새 공식문서 요약 (1)
      • HTML (Markup Language) (5)
    • 자바스크립트 (108)
      • 모던 자바스크립트 (31)
      • 개념 (31)
      • 정규표현식 (5)
      • 코드 스니펫 (1)
      • 라이브러리 (6)
      • 인터뷰 (24)
      • 웹개발자를 위한 자바스크립트의 모든 것 (6)
      • 팁 (2)
    • Typescript (49)
    • 리눅스와 유닉스 (10)
    • Computer Science (1)
      • Compiler (1)
    • IDE (3)
      • VSCODE (1)
      • IntelliJ (2)
    • 세미나 & 컨퍼런스 (1)
    • 용어 (개발용어) (16)
      • 함수형 프로그래밍 용어들 (1)
    • ORM (2)
      • Prisma (2)
    • NODEJS (2)
    • cypress (1)
    • 리액트 네이티브 (React Native) (31)
    • 러스트 (Rust) (15)
    • 코틀린 (Kotlin) (4)
      • 자바에서 코틀린으로 (4)
    • 정규표현식 (3)
    • 구글 애널리틱스 (GA) (1)
    • SEO (2)
    • UML (2)
    • 맛탐험 (2)
    • 리팩토링 (1)
    • 서평 (2)
    • 소프트웨어 공학 (18)
      • 테스팅 (16)
      • 개발 프로세스 (1)
    • 교육학 (1)
    • 삶의 지혜, 통찰 (1)
    • Chat GPT (2)
    • 쉘스크립트 (1)
    • 컴파일 (2)
    • Dart (12)
    • 코드팩토리의 플러터 프로그래밍 (4)
    • 플러터 (17)
    • 안드로이드 스튜디오 (1)
    • 윈도우즈 (1)
    • 잡다한 백엔드 지식 (1)
    • 디자인 패턴 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 팩터리 메서드 패턴
  • item9
  • 토비의 스프링
  • item7
  • 디자인패턴
  • rust
  • 객체복사
  • 자료구조
  • 알고리즘
  • 자바 검증
  • 참조 해제
  • Pre-rendering
  • 싱글톤 패턴
  • 메이븐 골
  • 추상 팩터리 패턴
  • 플라이웨이트패턴
  • 싱글턴
  • 메이븐 페이즈
  • 이펙티브자바
  • 자바스크립트 인터뷰
  • 싱글톤
  • try-with-resources
  • 서버리스 컴퓨팅
  • Java
  • 슬로우 쿼리
  • MSSQL
  • NEXT JS
  • 느린 쿼리
  • 작업기억공간
  • 빈 검증
  • item8
  • 자바 디자인패턴
  • 자바스크립트
  • 러스트
  • 메이븐 라이프사이클
  • 프로그래머의 뇌
  • serverless computing
  • next js app
  • bean Validation
  • 이펙티브 자바
  • Next.js
  • 자바
  • 도커공식문서
  • prerendering
  • 외래키 제약조건
  • pnpm
  • 자바스크립트 면접
  • Javadoc 자바독 자바주석 주석 Comment
  • 스프링 검증
  • 이펙티브 자바 item9

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Jake Seo

제이크서 위키 블로그

Java/자바 디자인 패턴

퍼사드 패턴 (Facade Pattern) 이란?

2023. 4. 18. 00:06

퍼사드 패턴 (facade pattern)

  • 라이브러리 혹은 프레임워크에 간소화된 인터페이스를 제공하는 패턴이다.
    • 클래스의 복잡한 시스템에 간소화된 인터페이스를 제공한다.
    • 클래스를 직접 사용하지 않는 것이 포인트이다.
  • 퍼사드란 건물의 대문같은 입구를 말한다.
    • 또 여기엔 내부 구조를 숨긴다는 의미도 내포되어 있다.
  • 복잡한 서브 시스템을 최대한 숨겨 의존성을 최소화하는 방법이다.

picture 2

자바 이메일 코드로 보는 퍼사드 패턴 예제

기존의 코드

  • 아래의 코드도 잘 돌아가며 잘못된 부분은 없다.
  • 그러나 몇가지 단점이 있다.
    • 테스트하기에 약간 힘든 코드이다.
    • 코드의 의도를 이해하기 위해 기술적인 부분까지 봐야 한다.
public class Client {
    public static void main(String[] args) {
        String to = "n00nietzsche@gmail.com";
        String from = "admin@naver.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("Test Mail from Java Program");
            message.setText("message");

            Transport.send(message);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }
}

개선된 코드

  • 개선 방법으로 기존 클라이언트 코드에서 3가지 관심사를 추출하고 그에 따른 클래스를 만들어줬다.
    • 메일을 보내기 위한 호스트를 설정하는 부분 (EmailHost)
    • 메일의 메세지를 설정하는 부분 (EmailMessage)
    • 메일을 보내는 부분 (EmailSender)

EmailHost 클래스

@Getter
public class EmailHost {
    private final Session session;

    public EmailHost(String host) {
        Properties properties = System.getProperties();
        properties.setProperty("mail.smtp.host", host);

        this.session = Session.getDefaultInstance(properties);
    }
}

EmailMessage 클래스

@Getter
@AllArgsConstructor
@Builder
public class EmailMessage {
    private final String to;
    private final String from;
    private final String title;
    private final String body;
    private final EmailHost host;

    public MimeMessage getMimeMessage() throws MessagingException {
        MimeMessage message = new MimeMessage(host.getSession());
        message.setFrom(new InternetAddress(from));
        message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
        message.setSubject(title);
        message.setText(body);

        return message;
    }
}

EmailSender 클래스

public class EmailSender {
    public static void send(EmailMessage emailMessage) {
        try {
            Transport.send(emailMessage.getMimeMessage());
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }
}

새롭게 개선된 Client 클래스

public class Client {
    public static void main(String[] args) {
        EmailHost host = new EmailHost("127.0.0.1");
        EmailSender.send(EmailMessage.builder()
                .to("n00nietzsche@gmail.com")
                .from("admin@naver.com")
                .title("안녕하세요.")
                .body("내용입니다.")
                .host(host)
                .build());
    }
}

개선해서 좋아진 점

  • API 사용자가 이용하기 훨씬 편리하다.
    • 프로토콜 설정, 세션 생성 등 기술적인 구현부를 볼 필요 없이 직관적으로 누구에게 보낼지 내용은 무엇인지 등만 설정하면 된다.
  • 테스트 코드를 작성하기도 훨씬 더 쉬워졌다.

조금 더 개선할 수 있는 점

  • 여러 메일 구현체를 이용해 이메일을 보낸다면, EmailSender 라는 인터페이스를 만들고 구현 방식에 따른 여러 EmailSender 구현체를 만들 수도 있을 것이다.

퍼사드 (Facade) 패턴의 장단점

장점

  • 서브 시스템의 의존성을 한 곳에 몰 수 있다.
  • 코드가 훨씬 읽기 편해진다.
  • 모든 API 를 다 노출시킬 필요가 없는 경우 유용하다.
    • API 사용자가 이용하기 훨씬 편하다.
    • 테스트코드를 작성하기 훨씬 편하다.

단점

  • 퍼사드 클래스가 서브 시스템에 대한 모든 의존성을 가지게 된다.
  • 기술적인 부분이 모두 무시되어 사용자 입장에서는 기술적인 이해도가 낮아질 수 있다.

퍼사드 (Facade) 패턴이 적용된 스프링 코드

  • 브릿지 패턴과 비교되는데 브릿지 패턴은 연결하려는 의도가 주된 의도였다면, 퍼사드 패턴은 기술적인 코드를 뒤로 감추려는 게 의도이다.
    • 디자인 패턴은 보는 시각에 따라 의도가 달라지므로 코드 하나에 어떤 패턴 하나만 적용되었다고 단순하게 판단하긴 어렵다.
  • JavaMailSenderImpl 은 MailSender 인터페이스를 내놓고 자바에서 메일을 보내는 기술적인 코드를 숨기고 있다.
    • MailSender 는 특정한 기술에 종속되어 있지 않다.
  • JdbcTransactionManager 도 PlatformTransactionManager 인터페이스를 내놓고 자바 트랜잭션 관리 기술을 숨기고 있다.
    • PlatformTransactionManager 인터페이스를 통해서 JDBC, JPA 등 다양한 플랫폼에서 트랜잭션을 관리할 수 있다.
  • 스프링 MVC 전체의 모든 API 를 퍼사드 패턴으로 볼 수도 있다.
    • 자바가 제공하는 서블릿을 감싸는 퍼사드로 볼 수 있다.
  • 스프링 WebFlux 는 동일한 스프링 애노테이션 등을 제공하지만 Reactive 로 동작하게 만들 수 있다.
public class FacadeInSpring {
    public static void main(String[] args) {
        MailSender mailSender = new JavaMailSenderImpl();
        PlatformTransactionManager platformTransactionManager = new JdbcTransactionManager();
    }
}

레퍼런스

  • 코딩으로 학습하는 GoF의 디자인 패턴
반응형
저작자표시 비영리 (새창열림)

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

프록시 패턴 (Proxy Pattern) 이란?  (0) 2023.04.25
플라이웨이트 패턴 (Flyweight Pattern) 이란?  (0) 2023.04.22
데코레이터 패턴 (Decorator Pattern) 이란?  (0) 2023.02.25
컴포지트 패턴 (Composite Pattern, 컴포짓 패턴) 이란?  (0) 2023.02.20
브릿지 패턴 (Bridge Pattern) 이란?  (0) 2023.02.19
    'Java/자바 디자인 패턴' 카테고리의 다른 글
    • 프록시 패턴 (Proxy Pattern) 이란?
    • 플라이웨이트 패턴 (Flyweight Pattern) 이란?
    • 데코레이터 패턴 (Decorator Pattern) 이란?
    • 컴포지트 패턴 (Composite Pattern, 컴포짓 패턴) 이란?
    Jake Seo
    Jake Seo
    ✔ 잘 보셨다면 광고 한번 클릭해주시면 큰 힘이 됩니다. ✔ 댓글로 틀린 부분을 지적해주시면 기분 나빠하지 않고 수정합니다. ✔ 많은 퇴고를 거친 글이 좋은 글이 된다고 생각합니다. ✔ 간결하고 명료하게 사람들을 이해 시키는 것을 목표로 합니다.

    티스토리툴바