Decorator Pattern

객체에 동적으로 새로운 책임을 추가할 수 있게 한다. 상속을 사용하지 않고도 객체의 기능을 확장할 수 있다. Motivation 어떤 기능을 추가하려면 기존 클래스를 계속 수정해야 하므로 OCP 원칙을 위반하게 된다. 즉, 새로운 기능을 추가할 때마다 새로운 클래스를 만들어야 한다. 데코레이터 패턴을 적용하면 기능을 동적으로 추가할 수 있으며, 코드의 재사용과 확장성이 증가한다. Applicability 동적이며 투명하게, 즉 다른 객체에 영향을 주지 않고 개별의 객체에 새로운 책임을 추가해야 할 때 제거될 수 있는 책임일 때 실제 상속으로 서브클래스를 계속 만드는 방법이 실질적이지 못할 때 Structure Component: 동적으로 추가할 기능을 가질 가능성들이 있는 객체에 대한 인터페이스 ConcreteComponent: 추가적인 기능이 실제 정의되어야 할 필요가 있는 객체 Decorator: Component 객체에 대한 참조자를 관리하면서 Component에 정의된 인터페이스를 만족하도록 인터페이스를 정의 ConcreteDecorator: Component에 새롭게 추가할 기능을 실제로 구현하는 클래스 Collaborations Decorator는 자신이 Component 객체 쪽으로 요청을 전달한다....

January 30, 2025 · 4 min · Beomsu Lee

Facade Pattern

한 서브시스템 내 인터페이스 집합에 대한 획일화된 하나의 인터페이스를 제공하는 패턴이다. 서브시스템을 사용하기 쉽도록 높은 수준의 인터페이스를 제공한다. 서브시스템이란 시스템의 컴포넌트로, 독립적이거나 부분적으로 독립적인 기능을 제공하는 하위 시스템을 의미한다. 즉, 전체 시스템을 구성하는 기능적인 부분들 중 하나로 특정 작업을 담당한다. Motivation 애플리케이션이 Scanner, Parser, ProgramNode 등의 컴파일러 서브시스템의 하위 클래스를 직접 사용하는 것은 복잡하고 어려운 작업일 수 있다. 퍼사드 패턴을 사용해 시스템의 복잡한 부분을 숨기고, 애플리케이션이 필요한 고수준 기능만 사용할 수 있게 한다....

January 30, 2025 · 4 min · Beomsu Lee

Flyweight Pattern

공유를 통해 많은 수의 세밀한(fine-grained) 객체들을 효과적으로 지원한다. Motivation 게임에서 각 객체가 같은 속성을 가지지만 다수의 인스턴스를 만들 경우, 이로 인해 메모리 낭비와 성능 저하가 발생될 수 있다. 예를 들어, 여러 객체가 같은 색상, 크기, 형태 등 공통된 속성을 가질 때, 이를 매번 새로 생성하는 것은 비효율적이다. Flyweight 패턴을 적용하면 공유 가능한 부분을 외부에서 관리하고, 변경 가능한 부분만 각 객체에 보관하여 메모리 사용을 최적화할 수 있다. Applicability 애플리케이션이 대량의 객체를 사용해야 할 때 객체의 수가 너무 많아져 저장 비용이 높아질 때 대부분의 객체 상태를 부가적인 것으로 만들 수 있을 때 부가적인 속성들을 제거하면 객체들이 동일한 특성을 가질 때 애플리케이션이 객체의 정체성에 의존하지 않을 때 Structure Flyweight 객체의 공유 방법은 다음과 같다....

January 30, 2025 · 5 min · Beomsu Lee

Proxy Pattern

다른 객체들에 대한 접근을 제어하기 위한 대리 객체(Proxy)를 사용한다. Motivation 사용자가 원격 서버의 대형 이미지를 로드하고 화면에 표시하는 애플리케이션을 개발한다고 하자. 이때 이미지 로딩이 느려 앱의 성능이 저하되는 문제가 발생할 수 있다. 프록시 패턴을 사용하면 실제 이미지를 즉시 로드하지 않고 가짜(Proxy) 객체를 먼저 생성한다. 이후 사용자가 이미지를 요청할 때 실제 객체를 로드하여 성능을 최적화한다. Applicability 원격지 프록시(remote proxy) 는 서로 다른 주소 공간에 존재하는 객체를 가리키는 대표 객체로, 로컬 환경에 위치한다....

January 30, 2025 · 4 min · Beomsu Lee

Adapter Pattern

클래스의 인터페이스를 사용자가 기대하는 인터페이스 형태로 변환시킨다. 서로 일치하지 않는 인터페이스를 갖는 클래스들은 함께 동작시킨다. Motivation 구식 라이브러리나 외부 라이브러리와 새로운 시스템이 호환되지 않는 문제가 발생할 수 있다. 예를 들어, 어떤 API는 기존 시스템에서 사용하는 인터페이스와 다르게 설계되어, 이를 그대로 사용이 불가능할 수 있다. 어댑터 패턴을 사용해 호환성을 맞춰줄 수 있다. Applicability 기존 클래스를 사용하고 싶은데 인터페이스가 맞지 않을 때 아직 예측하지 못한 클래스나 실제 관련되지 않는 클래스들이 기존 클래스를 재사용하고자 하지만, 이미 정의된 재사용 가능한 클래스가 지금 요청하는 인터페이스를 정의하고 있지 않을 때, 즉 이미 만든 것을 재사용하고자 하나 이 재사용 가능한 라이브러리를 수정할 수 없을 때 (Object Adapter만 해당) 이미 존재하는 여러 개의 서브클래스를 사용해야 하는데, 이 서브클래스들의 상속을 통해 이들 인터페이스를 다 개조한다는 것이 현실성이 없을 때, Object Adapter를 사용해 부모 클래스의 인터페이스를 변형하는 것이 더 바람직함 Structure Class Adapter Class Adapter는 다중 상속을 활용해 한 인터페이스를 다른 인터페이스로 적응시킨다....

January 28, 2025 · 5 min · Beomsu Lee