카테고리 없음
[디자인패턴] 구조,생성 패턴
초코chip
2024. 9. 19. 21:31
구조 패턴
- 클래스나 객체를 조합해 더 큰 구조를 만드는 패턴
데코레이터 패턴
- 정의: 객체의 결합을 통해 기능을 동적으로 유연하게 확장 할 수 있게 해주는 패턴
- 목적: 기존 클래스에 여러 추가 기능들을 조합해서 확장을 해야할 때 사용
배경
- SW를 개발할 때, 객체에 새로운 기능을 추가해야 할 경우가 자주 발생
- 이때, 상속을 사용해 클래스를 확장하는 방식이 일반적이지만, 상속은 클래스가 많아질수록 코드가 복잡해지고 유지보수가 어려움
- 특히, 각 기능을 조합할 때마다 새로운 클래스를 만들어야 하는 비효율성이 발생

![]() |
![]() |
해결
- 상속 대신 객체를 동적으로 감싸 추가 기능을 더하는 방식으로 진행하자!
- 즉, 필요한 기능만을 추가하고 조합할 수 있어 코드의 중복을 줄이고 관리가 용이

![]() |
![]() |
퍼사드 패턴
- 정의: 복잡한 서브 클래스들의 공통적인 기능을 정의하는 상위 수준의 인터페이스를 제공하는 패턴
- 목적: 복잡한 시스템의 내부 동작을 숨기고, 단순한 인터페이스를 제공해 사용자가 쉽게 기능을 사용할 수 있도록 돕기 위해
배경
세탁을 하기 위해서는 크게 Washing, Rinsing, Spinning과 같은 동작들이 필요

![]() |
![]() |
> 클라이언트가 여러 객체들에 결합되어, 유지보수에 용이하지 않음
해결
Washing, Rinsing, Spinning과 같은 동작들을, Facade Object를 통해 '세탁'이라는 행위에 필요한 공통 기능으로 정의

![]() |
![]() |
> 이렇게 하면 클라이언트는 서브 시스템들의 코드를 몰라도, Facade Object만 알면 사용이 가능 + 서브 시스템들간의 복잡한 결합도 또한 낮출 수 있다.
어댑터 패턴
- 정의: 서로 호환되지 않는 인터페이스를 가진 클래스들이 함께 동작할 수 있도록 중간에 변환기를 제공하는 패턴
- 목적: 기존 코드를 수정하지 않고도 다른 인터페이스와 호환되도록 하기 위해
배경
- 기존 코드에서 사용 중인 클래스와 새로 도입하려는 클래스의 인터페이스가 달라서 직접 사용하기 어려움
- 이를 해결하기 위해서는 기존 코드를 수정해야 하는데, 이는 유지보수나 확장성에 좋지 않음
![]() |
![]() |
해결
- 기존 클래스와 새 클래스를 연결하는 어댑터를 만들어, 수정 없이 두 클래스가 함께 작동할 수 있게 하자!
![]() |
![]() |
생성 패턴
- 객체를 생성하는 과정을 효율적으로 관리하기 위한 디자인 패턴
추상 팩토리 패턴
- 정의: 객체 생성 과정을 추상화한 인터페이스를 제공하는 패턴
- 목적: 객체 생성을 캡슐화함으로써 구체적인 타입을 감추고 느슨한 결합 구조를 표방하기 위해
배경
클라이언트가 구체 클래스에 직접 의존하는 경우
![]() |
![]() |
> 나중에 다른 핸드폰으로 교체하려면 클라이언트 코드 수정 필요 -> 확장성이 좋지 않음
해결
추상 팩토리 패턴을 적용해 객체 생성에 대한 추상화가 이루어, 클라이언트 코드가 구체적인 클래스에 의존하지 않게 하자!

![]() |
![]() |
![]() |
-> 팩토리 인터페이스를 통해 객체를 생성하므로 유지보수와 확장성이 향상
+ 팩토리메서드 vs 추상팩토리 패턴
- 공통점: 둘다 구체적인 객체 생성 과정을 추상화한 인터페이스를 제공
- 차이점:
- 팩토리 메서드 패턴은 팩토리를 구현하는 방법에 초점
- 추상 팩토리 패턴은 팩토리를 사용하는 방법에 초점