디자인패턴
디자인패턴(Design Pattern) 개념
(20년 4회)
- 객체 지향 프로그래밍 설계 시, 자주 발생하는 문제들에 대해 재사용할 수 있도록 만들어 둔 패턴 모음
- 이미 만들어져서 잘 되는 것을 활용하여 재사용함으로써 프로그램 최적화에 도움을 줌
- 효율적인 코드를 만들기 위한 방법론
- 소프트웨어 구조 파악 용이
- 구성요소: 패턴 이름 / 문제 / 솔루션 / 사례 / 결과 / 샘플코드(20년2회)
GoF 디자인패턴
- 23가지 디자인패턴 정리
- 각각의 디자인패턴을 생성/구조/행위 3가지로 분류(20년 4회)
- 각 패턴이 어디에 속하는지 알아두기(20년 1, 2회)
생성 패턴⭐️
- 객체의 인스턴스 생성을 추상화하는 방법
- 객체의 생성 과정과 인스턴스화를 캡슐화하여 특정 상황에서 어떤 객체를 생성할지 결정할 수 있게 도와줌
추상 팩토리(Abstract Factory)
- 구체적인 클래스에 의존하지 않고, 서로 연관/의존하는 객체들을 그룹으로 생성해 추상적으로 표현
빌더(Builder)
- 객체의 생성과정과 표현방법 분리 → 동일한 객체 생성에도 서로 다른 결과
new User.Builder(10)
.name("name")
.password("password")
.age(12)
.build();
팩토리 메소드(Factory Method)
(20년 2회)
- 객체 생성을 서브클래스로 위임하여 캡슐화함
- Virtual-Constructor 패턴이라고도 함
프로토타입(Prototype)
- 원본 객체를 복제함으로써 객체를 생성함
- java의
clone()
을 이용해 생성하고자 하는 객체에 clone()
에 대한 재정의(Override)
를 해준다
싱글톤(Singleton)
- 어떤 클래스의 인스턴스를 하나임을 보장하고, 어디서든 참조할 수 있도록 함
public class Car {
private static Car car = new Car();
private Car() {}
public static Car getInstance() {
return car;
}
}
구조 패턴⭐️
- 클래스나 객체를 조합해 더 큰 구조를 만드는 패턴
- 상속을 통해 클래스나 인터페이스를 합성하는 방법 정의
어댑터(Adapter)
- 호환성이 없는 클래스 인터페이스를 이용할 수 있도록 변환해주는 패턴
브리지(Bridge)
- 구현부에서 추상층을 분리하여, 각자 독립적으로 확장 및 다양성을 가지는 패턴
interface Shape {
public void draw();
}
class Circle implements Shape {
public void draw() {
printf("Circle");
}
}
class Square implements Shape {
public void draw() {
printf("Square");
}
}
컴포지트(Composite)
- 객체들의 관계를 트리구조로 구성하여 가진 복합/단일 객체를 구분 없이 다룸
- 하나 이상의 유사한 객체를 묶어서 설계된 객체로 모두 유사한 기능을 나타냄
데코레이터(Decorator)
- 상속하지 않고도 개개의 기능을 동적으로 확장해주는 패턴
파사드(Façade)
- 서브클래스들의 기능을 간편하게 사용할 수 있도록 하는 패턴(예: 리모콘)
- 서브클래스들에 대해 하나의 통합된 인터페이스를 제공(Wrapper)
- 클래스 간 의존관계가 줄어들고 복잡성 감소
플라이웨이트(Flyweight)
- 크기가 작은 여러 개의 객체를 매번 생성하지 않고, 공유해서 메모리를 절약하는 패턴
프록시(Proxy)
- 접근이 어려운 객체를 연결해주는 인터페이스 역할을 수행하는 패턴
행위 패턴
- 객체나 클래스들이 상호작용하는 방법 및 책임을 정의하는 패턴
- 객체 사이의 효율적인 커뮤니케이션과 책임 할당을 도움
책임 연쇄(Chain of Responsibility)
- 한 객체가 처리하지 못하면 다음 객체로 넘어가는 패턴
- 객체들은 연쇄적으로 연결되어있으며, 각 객체는 요청을 처리하거나 전달함
커맨드(Command)
- 요청에 사용되는 각종 명령어들을 추상, 구체클래스로 분리하여 단순화함
- 실행될 기능을 캡슐화함으로써 주어진 조건을 만족하는 기능을 실행할 수 있는 유연성 제공
- 요청 자체를 객체로 감싸서 전달함으로써, 로그, 큐관리, undo-redo 등의 기능을 구현 가능
인터프리터(Interpreter)
반복자(Interator)
- 동일한 인터페이스를 사용하도록 하는 패턴
- 컬랙션 내부 구조를 노출시키지 않고도, 그 원소들에 접근할 수 있는 방법들 제공
- 이를 통해 단일 원칙 적용을 유지하면서도, 컬랙션에 대한 반복 작업 수행 가능
- 서로의 존재를 모르는 상태에서도 협력할 수 있게 하는 패턴
- 객체 간 복잡한 상호작용은 캡슐화하고, 객체들이 서로 직접 참조하지 않도록 중재자 객체를 통해 통신
- 이를 통해 시스템을 더 잘 조직화하고 결합도를 낮출 수 있음
메멘토(Memento)
- 객체의 상태정보를 저장하고 이전상태로 복원할 수 있는 기능 제공하는 패턴
옵저버(Observer)
- 관찰대상의 변화를 탐지하는 패턴
- 이를 통해 상태의 일관성 유지 가능
상태(State)
- 객체의 상태에 따라 동일한 동작을 다르게 처리해야할 때 사용하는 패턴
- 이를 통해 객체의 상태 전이 방식을 더 명확하게 표현 가능
전략(Strategy)
- 클라이언트에 영향을 받지 않고 독립적이도록 알고리즘을 캡슐화하는 패턴
- 이를 통해 알고리즘을 쉽게 바꿔 사용할 수 있음
템플릿 메서드(Template Method)
- 유사한 서브클래스를 묶어 공통된 내용을 상위클래스에 정의하는 패턴
- 상위클래스는 알고리즘의 골격만을 작성하고, 구체적인 처리는 서브클래스로 위임
방문자(Visitor)
- 필요할 때 마다 해당 클래스에 방문해서 처리하는 패턴
- 객체 구조를 이루는 원소에 대한 연산을 정의하는데 사용
- 이를 통해 새로운 연산을 추가하더라도 그 객체 구조를 변경하지 않아도 됨
- 개방폐쇄원칙 적용