본문 바로가기

개발/디자인패턴

구조 개선을 위한 디자인패턴(2)

장세찬, 『GoF 디자인 패턴! 이렇게 활용한다. : C++로 배우는 패턴의 이해와 활용』, 한빛미디어(2004)

책의 내용을 배끼기보단 제가 이해한 내용을 위주로 작성해서 틀린 부분이 있을 수 있습니다!


5. Facade 패턴

프로그램 설계는 보통 class나 객체를 기준으로 많이 표현하죠.
그런데 클래스가 너어어무 많아지면 설계도도 복잡해지고 이해하기 위해 필요한 시간은 더더욱 길어집니다.
그래서 이런 일을 방지하기 위해 서브시스템이라는 개념이 만들어졌습니다. 정해진 일을 하는 서브시스템을 구현하고, 그 서브시스템과는 하나의 인터페이스로만 이어져있는 방식이죠.
이렇게 서브시스템과 클라이언트 부분을 분리해 구현하는 방식을 Facade 패턴이라고 합니다.

책에 나온 Database를 예로 들어보겠습니다.
클라이언트는 DB를 사용하기 위해 쿼리 생성, 쿼리 실행, 결과 취득, 파싱과 같은 작업을 해야합니다.
하지만 이 과정을 DBHandler라는 클래스가 모두 해준다면, 클라이언트는 이 핸들러 클래스에 요청하는 것으로 필요한 데이터를 취득할 수 있습니다.
이를 위한 과정은 DBHandler 뒷단에 온전히 맞기는 것이죠.


서브시스템과 클라이언트의 결합도를 현저히 줄일 수 있는 패턴이라 잘만 사용하면 대형 프로젝트에서는 가장 유용한 패턴일 것 같습니다!

6. Flyweight 패턴

객체는 보통 객체 별 고유 데이터와 특성을 갖게 해서 개별적으로 사용하죠.
하지만 이렇게 모든 객체가 고유의 데이터를 각각 가질 경우, 메모리 낭비를 유발하는 원인이 되기도 합니다.
그래서 여러 객체가 동일하게 사용하는 데이터의 경우, 이 데이터는 공유하도록 하는게 현명하죠.
이를 위한 디자인 패턴이 Flyweight 패턴입니다. 여기서 공유하는 자원, 즉 외부에 따로 빼서 관리할 데이터는 Extrinsic State이라 합니다. 반대로 내부에서 고유하게 갖고있는 데이터는 Intrinsic State이라 구분합니다.

이 그림을 예로 들면  Extrinsic State는 aConcreteFlyweight가 되겠네요!

그런데 항상 “공유”의 개념이 들어가면 주의해야할 사항들이 많아지죠. 아래는 그 주의해야 할 내용들입니다.

1) 패턴 사용 여부 결정하기
Flyweight 패턴 사용 여부는 크게 두 가지 요인에 따라 결정됩니다
- Extrinsic State와 Intrinsic State구분 시의 효율
- Extrinsic State와 Intrinsic State을 구분할 수 있는 명확한 기준

2) 공유 객체의 생성
공유 객체 즉, Extrinsic State의 생성은 Intrinsic에서 하는 것이 좋습니다.
클라이언트가 직접 수행할 경우, 공유 과정의 문제가 생길 수 있고 또 생성/삭제/수정 시에 관련된 모든 Intrinsic State를 신경써야 하기 때문입니다.
이를 방지하기 위해 대표적으로 Factory Method, Singleton 둘 중 하나의 패턴을 활용합니다.

3) 공유 객체의 소멸
공유객체를 더이상 사용하지 않는 경우, 이 객체를 소멸시켜야 메모리 효율을 높일 수 있죠.
하지만 이 객체가 더이상 공유되지 않는다는 것을 어떻게 알 수 있을까요?
공유객체가 자신을 공유하는 객체의 개수를 카운팅하는 방법이 가장 대표적인 방법입니다. 이 값이 0이 되면 객체를 소멸시키는 방법이죠.
이를 Reference Counting기법이라 합니다.

7. Proxy 패턴

Proxy패턴은 쉽게 말하면 사용자와 기능(class)간의 대리자를 두는 패턴입니다.

class A { 
	void func();
}

class Proxy : public A {
	void func() {
		A val;
		val.func();
	}
}

int main() {
	Proxy val;
	val.func();
}

이렇게 클래스 A를 바로 호출하지 않고 클래스 Proxy를 통해서 호출하는 식인거죠.

중간에 끼인 Proxy 클래스에서는 흐름제어나 보안을 위한 역할을 합니다.
Proxy 패턴을 사용하는 대표적인 사례는 클래스 A의 func가 리소스를 많이 쓰는 작업인 경우인데요, 이 경우엔 중간자인 Proxy 클래스에서 캐시 작업을 해서 리소스를 줄이는 역할을 한다고 하네요.

그런데 사실, 캐시를 하는건 이해가 가지만 왜 리소스를 줄일 수 있는 방법인건지는 이해하기가 힘드네요...
공부를 하고, 직접 개발해서 테스트해봐야 알 수 있는 패턴인 것 같아요(저도 아직 제대로 이해를 못해서ㅠㅠ)



'개발 > 디자인패턴' 카테고리의 다른 글

구조 개선을 위한 디자인패턴  (0) 2020.12.10
객체 생성 관련 디자인패턴  (0) 2020.11.21