Java 디자인 패턴-08.Facade

(Java 디자인 패턴 스터디 모집 중 : https://github.com/bluedskim/javaDesignPatterns)

Facade 패턴 다이어그램

Facade Design Pattern | Introduction

(출처:https://www.geeksforgeeks.org/facade-design-pattern-introduction/)

해결하려는 문제

  1. 클라이언트에서 다른 객체들로의 참조들을 분리하여 클라이언트의 의존성을 줄이고 복잡성을 관리.

특징/용도

  1. 구조적structural 디자인 패턴
  2. 클라이언트에 Facade라는 단순화 된, 필요한 기능만 접근할 수 있는 레이어를 추가
  3. 서드파티 라이브러리에 대한 직접적 의존성을 제거하여 교체를 쉽게 한다.
  4. facade는 캡슐화된encapsulated 블랙박스.

구성요소

  1. facade : target의 여러 인터페이스를 조합한 루틴이 정의된 객체
  2. target : 원래는 클라이언트가 직접 참조해야 하는 객체
  3. client : facade를 통해 target들을 사용(호출)하는 객체

고려사항

다른 유사한 패턴을 사용할 수도 있다.

  1. Decorator : 원래의 소스를 감싸는 방식으로 인터페이스에 동적으로 기능을 추가한다.
  2. Delegation : 상속을 통한 조합
  3. Adapter : 어떤 인터페이스를 다른 인터페이스로 변환

클래스 다이어그램

Adapter 패턴(김동석)

소스

  1. facade : ShapeMaker.java
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    
    package net.dskim.desingpattern.facade;
    
    /**
     * facade용 클래스
     */
    public class ShapeMaker {
    	private Shape circle;
    	private Shape rectangle;
    	private Shape square;
    
    	public ShapeMaker() {
    		circle = new Circle();
    		rectangle = new Rectangle();
    		square = new Square();
    	}
    
    	public String drawCircle() {
    		return circle.draw();
    	}
    
    	public String drawRectangle() {
    		return rectangle.draw();
    	}
    
    	public String drawSquare() {
    		return square.draw();
    	}
    
    	/**
    	 * 복잡한 로직을 감싼 facade 메소드
    	 * @return
    	 */
    	public String drawAllShape() {
    		return circle.draw() + rectangle.draw() + square.draw();
    	}
    }
  2. target : Shape.java, Circle.java, Rectangle.java, Square.java
    • Shape.java
      1
      2
      3
      4
      5
      
      package net.dskim.desingpattern.facade;
      
      public interface Shape {
      	String draw();
      }
    • Circle.java
       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      
      package net.dskim.desingpattern.facade;
      
      import lombok.extern.slf4j.Slf4j;
      
      @Slf4j
      public class Circle implements Shape {
      
      	@Override
      	public String draw() {
      		String result = "Circle::draw()";
      		log.info(result);
      		return result;
      	}
      }
    • Rectangle.java
       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      
      package net.dskim.desingpattern.facade;
      
      import lombok.extern.slf4j.Slf4j;
      
      @Slf4j
      public class Rectangle implements Shape {
      
      	@Override
      	public String draw() {
      		String result = "Rectangle::draw()";
      		log.info(result);
      		return result;
      	}
      }
    • Square.java
       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      
      package net.dskim.desingpattern.facade;
      
      import lombok.extern.slf4j.Slf4j;
      
      @Slf4j
      public class Square implements Shape {
      
      	@Override
      	public String draw() {
      		String result = "Square::draw()";
      		log.info(result);
      		return result;
      	}
      }
  3. client : ShapeMakerTest.java
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    
    package net.dskim.desingpattern.facade;
    
    import static org.junit.jupiter.api.Assertions.assertEquals;
    
    import org.junit.jupiter.api.Test;
    
    public class ShapeMakerTest {
    
    	@Test
    	public void ShapeMakerFacadeTest() {
    		ShapeMaker shapeMaker = new ShapeMaker();
    		assertEquals("Circle::draw()", shapeMaker.drawCircle());
    		assertEquals("Rectangle::draw()", shapeMaker.drawRectangle());
    		assertEquals("Square::draw()", shapeMaker.drawSquare());
    		assertEquals("Circle::draw()Rectangle::draw()Square::draw()", shapeMaker.drawAllShape());
    	}
    }

참고