[Design Pattern] 퍼사드 패턴

이재훈·2023년 8월 22일
1

디자인패턴

목록 보기
2/6

자주 사용되는 디자인 패턴

퍼사드 패턴

앞의 게시글의 어댑터 패턴보다 더 자주 사용하게 되는 패턴인 퍼사드 패턴입니다.

Facade는 건물의 정면의 의미합니다. 건물 내부의 복잡함을 숨기고 건물의 정면만을 나타나게 합니다. 사용자들은 건물의 정면에 있는 출입구를 통해 내부를 이용하게 됩니다.
건물의 정면이 마치 인터페이스가 되는 것입니다. 클라이언트는 건물 정면에 보이는 출입구 즉 인터페이스만 사용하게 되는 것입니다.

개발 과정에서 만나게 되는 퍼사드 패턴이 필요한 상황1

동영상 분석 요청이 있습니다. 순서는 아래와 같습니다.

  1. 동영상 URL을 받는다.
  2. 동영상을 다운로드한다.
  3. 동영상을 인코딩한다.
  4. 분석 피처 추출한다.
  5. 피처를 활용하여 분석한다.
  6. 분석 결과를 저장한다.

위의 내용을 토대로 코드를 예시로 작성해보도록 하겠습니다. 내부적인 구현은 되어있지 않습니다.

class SomeService {
	private FileDownloader fileDownloader;
    private VideoEncoder videoEncoder;
    private VideoFeatureExtractor videoFeatureExtractor;
    private VideoAnalyzer videoAnalyzer;
    private FeatureRepository featureRepository;
    
    // 위 의존성은 주입되어 있다고 가정
    
    public VideoAnalysisResult analyzeVideo(String videoUrl) {
    	String filePath = fileDownloader.download(videoUrl);
        String encodedFilePath = videoEncoder.encode(filePath);
        VideoFeature videoFeature = videoFeatureExtractor.getFeature(encodedFilePath);
        VideoAnalysisResult videoAnalysisResult = videoAnalyzer.anlyze(videoFeature);
        featureRepository.save(videoAnalysisResult);
        
        // 다른 코드
        return videoAnalysisResult;
    }
}

이 코드에는 문제가 없습니다. 하지만 SomeService 외에 다른 AnotherService 클래스가 생성되었다고 가정해보겠습니다.

class AnotherService {
	private FileDownloader fileDownloader;
    private VideoEncoder videoEncoder;
    private VideoFeatureExtractor videoFeatureExtractor;
    private VideoAnalyzer videoAnalyzer;
    private FeatureRepository featureRepository;
    
    // 위 의존성은 주입되어 있다고 가정
    
    public VideoAnalysisResult analyzeVideo(String videoUrl) {
    	String filePath = fileDownloader.download(videoUrl);
        String encodedFilePath = videoEncoder.encode(filePath);
        VideoFeature videoFeature = videoFeatureExtractor.getFeature(encodedFilePath);
        VideoAnalysisResult videoAnalysisResult = videoAnalyzer.anlyze(videoFeature);
        featureRepository.save(videoAnalysisResult);
        
        // 다른 코드
        return videoAnalysisResult;
    }
}

중간에 중복되는 로직이 존재하지만 내부에 다른 코드가 존재하는 상황입니다. 이런 상황이 퍼사드패턴이 필요한 상황입니다.


여기에 퍼사드 패턴을 활용하게 되면 아래와 같이 바뀝니다.

FacadeVideoAnalyzer는 동영상 URL을 입력 받아 동영상 다운로드 부터 분석 결과를 저장하는 모든 내부 과정을 캡슐화 해버립니다. SomeSerivice와 AnotherService는 내부 과정을 모르더라도 상관이 없어집니다. 만약 다른 Service가 추가된다고 하더라도 문제될 것이 없습니다. 퍼사드 패턴이 적용된 코드는 아래와 같습니다.

class SomeService {
	private FacadeVideoAnalyer facadeVideoAnalyzer;

    // 위 의존성은 주입되어 있다고 가정
    
    public VideoAnalysisResult analyzeVideo(String videoUrl) {
		VideoAnalysisResult videoAnalysisResult = facadeVideoAnalyzer.analyze(videoUrl);
        
        // 다른 코드
        return videoAnalysisResult;
    }
}
class AnotherService {
	private FacadeVideoAnalyer facadeVideoAnalyzer;

    // 위 의존성은 주입되어 있다고 가정
    
    public VideoAnalysisResult analyzeVideo(String videoUrl) {
		VideoAnalysisResult videoAnalysisResult = facadeVideoAnalyzer.analyze(videoUrl);
        
        // 다른 코드
        return videoAnalysisResult;
    }
}
class FacadeVideoAnalyer {
	private FileDownloader fileDownloader;
    private VideoEncoder videoEncoder;
    private VideoFeatureExtractor videoFeatureExtractor;
    private VideoAnalyzer videoAnalyzer;
    private FeatureRepository featureRepository;
    
    // 위 의존성은 주입되어 있다고 가정
    
    public VideoAnalysisResult analyzeVideo(String videoUrl) {
    	String filePath = fileDownloader.download(videoUrl);
        String encodedFilePath = videoEncoder.encode(filePath);
        VideoFeature videoFeature = videoFeatureExtractor.getFeature(encodedFilePath);
        VideoAnalysisResult videoAnalysisResult = videoAnalyzer.anlyze(videoFeature);
        featureRepository.save(videoAnalysisResult);
        
        return videoAnalysisResult;
    }
}

개발 과정에서 만나게 되는 퍼사드 패턴이 필요한 상황2


위의 그림은 실무에서 사용하는 Controller-Service 구조를 나타낸 것입니다. 여기서 문제는 userService와 ArticleService가 서로를 참조할 때 문제가 발생합니다. 순환참조 문제도 발생하고 또한 변경에 대한 영향을 서로 준다는 것이 문제입니다.

퍼사드 패턴을 사용하면 위와 같이 변경할 수 있습니다. 단독으로 제공할 수 있는 기능은 컨트롤러에서 UserService 또는 ArticeService를 사용하고 만약 둘 다의 기능을 사용해야하는 경우에는 FacadeUserAndArticleService를 사용하여 호출하게 됩니다.
순환 참조 문제가 해결됩니다.

퍼사드 패턴이 적용되면서 생긴 장점과 퍼사드 패턴이 보호하고자 하는 것


퍼사드 패턴을 사용하게 되면 복잡한 라이브러리 API 호출을 캡슐화하여 간단한 인터페이스만으로도 동일한 동작을 가능하게 됩니다. 내부의 로직이 변경되더라도 변경의 범위는 Service가 아닌 Facade 패턴을 사용한 클래스까지 입니다. Service 클래스가 보호 받게 되는 것 입니다.
또한, 새로운 서비스가 추가되더라도 변경할 코드는 존재하지 않습니다.

결론

퍼사드 패턴은 실무에서 굉장히 많이 사용되게 되는 패턴 중 하나입니다. 반복되는 코드를 줄이고 복잡한 내부로직을 캡슐화하여 좀 더 객체지향적으로 코드를 작성할 수 있게 해주는 패턴입니다.


해당 게시글은 프로그래머스 스쿨 강의
"실무 자바 개발을 위한 OOP와 핵심 디자인 패턴(푸)"
를 정리한 내용입니다. 쉽게 잘 설명해주시니 여러분도 강의를 듣는 것을 추천드립니다.

profile
부족함을 인정하고 노력하자

0개의 댓글