원문 링크 :
파사드 디자인 패턴은 하나 이상의 컴포넌트(클래스, 모듈, 서비스)등을 하나의 인터페이스를 통해 노출시키는 것이다.
파사드 디자인 패턴은 엔터프라이즈 어플리케이션에서 많이 사용되는데 복잡한 것을 처리하기 쉽고 도입하기 쉽기 때문이다.
나는 엔터프라이즈 어플리케이션에서 파사트 패턴을 사용하는 것을 많이 받고 3가지 예시로 설명할 수 있다.
1. 라이브러리로부터 어플리케이션 디커플링하기
써드파티 라이브러리는 재사용가능한 기능을 제공하는 클래스들의 모음이다. 개발자는 프로젝트에 라이브러리를 포함시키고 난 뒤부터는 클래스를 직접적으로 어플리케이션에 주입해서 사용할 수 있다.
그러나, 라이브러리를 직접 참고하는 것은 라이브러리와 강하게 커플링된다는 점에서 항상 좋은 해결책은 아니다. 특정 버전의 라이브러리에 종속될 수도 있다. 특히 어플리케이션이 라이브러리를 많이 사용할수록, 라이브러리를 다른 라이브러리로 교체하거나 혹은 버전업 하는 것은 더 어려워진다. 개발자들은 수많은 곳에서 쓰고 있는 라이브러리를 바꾸어야 하기 때문이다.
써드파티 라이브러리로부터 어플리케이션 코드릴 디커플링하기 위해서, 개발자는 파사드를 둘 수 있다.
이 예시에서 파사드 사용은 비교적 간단하다. 파사드 객체는 라이브러리를 감싸는 객체이다. 이 클래스는 어플리케이션으로부터의 호출을 라이브러리 코드로 리다이렉트 시켜준다.
특정 라이브러리를 새로운 라이브러리로 바꿔주고자 할때, 개발자는 파사드 객체 내부 코드만 재작성하면 된다. 파사드 도입 전의 많은 부분들을 리펙토링할 필요가 사라진다.
주의해야할 것은 파사드를 쓰더라도, 어플리케이션 코드에서 직접 라이브러리를 사용할 수 있는 방법이 있다는 것이다.
라이브러리를 직접적으로 호출하는 것을 막는 방법이 있다.
- 어플리케이션에서 별도 프로젝트를 생성해서 파사드를 넣는다.
- 써드 퍼티 라이브러리를 파사드하는 프로젝트에 대한 참조를 넣는다.
- 파사드만을 쓰는 프로젝트를 어플리케이션에 참조를 넣는다.
파사드를 쓰면 좋은 점은 개발자가 프로젝트에서 라이브러리 혹은 버전마저도 파사드를 하나씩 둘 수 있다는 것이다. 프로젝트 간에서 혹여나 라이브러리를 교체해야 한다 할지라도, 개발자는 새로운 파사드를 등록해서 사용하면 된다.
2. 새로운 어플리케이션에서 레거시를 재사용하기
레거시 어플리케이션은 비즈니스 상황에 따라 새로운 기능을 추가해야 한다. 이 새로운 기능은 레거시 코드에 직접 구현할 수도 있다. 그러나, 레거시코드를 실제 작성한 사람들은 비교적 안정적으로 구축할 수 있지만,
만약, 새로운 팀이라면, 그들은 맨 처음부터 레거시 어플리케이션을 다시 작성을 해야만 새로운 기능을 구축할 수 있다. 그러나, 클라이언트 입장에서는 비교적 비용이 더 들 것이며 몇 달 혹은 몇 년을 기다릴 수 없을 것이다. 이때 사용할 수 있는 것이 파사드 이다.
새로운 기능을 또다른 모듈로 만들고 레거시 코드를 재사용하는 것이다.
이 접근법에도, 새로운 시스템의 부분은 레거시 코드와 강하게 커플링 되어 있을 수 있다.
이 커플링을 피하기 위해, 개발자는 레거시 어플리케이션의 기능을 파사드를 통해 노출시킬 수 있다. 그렇게 하면, 새로운 시스템은 레거시 코드와 참조를 가지고 있을 필요가 없도록 된다.
파사드는 레거시 어플리케이션의 컴포넌들 사이의 복잡한 호출을 캡슐화하고 단순화한다. 이것은 새로운 코드가 레거시 코드의 구현방식을 몰라도 사용할 수 있다는 것을 의미하고, 더 쉽게 유지보수 하게 된다.
주의해야할 것은 파사드가 별도 프로젝트의 한 부분이 될 수 있다는 것이다. 새로운 코드는 프로젝트를 파사드로만 참조할 수 있고, 어느 누구도 레거시 코드를 직접 호출할 수 없게 된다.
3. 인터페이스 분리 원칙을 구현하기
몇몇 클래스나 라이브러리들 중에는 여러 클라이언트에서 사용되는 복잡한 기능을 캡슐화할 수 있다. 이런 다른 클라이언트들은 용도가 다를 수 있는데, 예를 들어 첫번째 클라이언트는 5%만 쓰고, 두번째 클라이언트는 50%만 사용할 수 있게 된다.
이 예시에서 인터페이스 분리 원칙이 위배되는데, 이 복잡한 클래스는 클라이언트마다 적절하게 사용되기 어려워진다.
개발자는 복잡한 클래스를 작은 클래스들로 분리하려고 하지만 다음 같은 이유에서 어려울 수 있다.
- 복잡한 클래스가 개발자가 접근할 수 없는 완전 분리된 라이브러리라면 불가능해지는 경우도 있다.
- 만약 개발자가 접근할 수 있더라도, 라이브러리는 이미 많은 클라이언트에서 사용되고 있을 수 있다. (이렇게 되면 이 라이브러리를 리펙토링하면 모든 클라이언트에게 영향을 주게 된다.)
- 만약 이 클라이언트에서만 쓴다고 하더라도, 이미 레거시 코드가 되어서, 리펙토링하는 것이 여러 이슈를 낼 수 있다.
이 경우, 각각 클라이언트마다 각각의 파사드를 만듦으로써 해결할 수 있다. 위의 예시에서 첫번째 파사드는 5%만 가져가고, 두번째는 50%만 가져가게 할 수 있다.
새로운 클라이언트는 존재하는 파사드를 여러번 재사용하고나서, 각각의 클라이언트는 복잡한 클래스를 가지고 고민할 필요가 없게 된다.
결론
파사드는 어플리케이션의 추상화 레벨이다. 추상화는 개발자들이 낮은 커플링을 만들어주고, 재사용성을 증가시키고, 복잡한 인터페이스를 단순화하고, 클라이언트로부터 구현내용을 숨긴다. 그러나 추상화는 어플리케이션의 복잡성을 증가시키고 복잡한 추상화는 성능을 낮추게 된다. 그러므로, 개발자는 도입전에 항상 장점과 단점을 분석해야한다.
'개발' 카테고리의 다른 글
git. merge strategy (1) | 2023.10.24 |
---|---|
[chrome plugin] 단축키로 크롬 플러그인 연동 (suggested_key) (0) | 2023.09.30 |
[chrome plugin] 크롬 플러그인 샘플 코드 작성해보기 (feat. development-basics) (0) | 2023.09.22 |
strong consistency vs eventual consistency (0) | 2023.06.18 |
레이어드 아키텍처 (계층형 아키텍쳐)와 헥사고날 아키텍처 (육각형 아키텍쳐) (1) | 2022.11.13 |