본문으로 바로가기

[DP] 2. 디자인 패턴 (Design Pattern)

category CS/Design Pattern 2019. 5. 1. 19:22
2_디자인 패턴

2. 디자인 패턴 (Design Pattern)

  1. 디자인 패턴이란?
  2. 스트래티지 패턴
  3. 싱글턴 패턴
  4. 옵서버 패턴
  5. 템플릿 메서드 패턴
  6. 팩토리 메서드 패턴

 

1. 디자인 패턴이란?

소프트웨어를 설계할 때, 특정 맥락에서 자주 발생하는 고질적인 문제들이 또 발생했을 때 재사용 을 통해 해결할 수 있는 방법이다.

  • 바퀴를 다시 발명하지 마라 (Don't reinvent the wheel)
  • 이미 만들어져서 잘 되는 것을 처음부터 다시 만들 필요가 없다는 의미이다

 

 

2. 스트래티지 패턴

행위를 클래스로 캡슐화해 동적으로 행위를 자유롭게 바꿀 수 있게 해주는 패턴이다. 같은 문제를 해결하는 여러 알고리즘이 클래스별로 캡슐화 되어 있고, 이들이 필요할 때 마다 교체할 수 있도록 함으로써 동일한 문제를 다른 알고리즘으로 해결할 수 있게 해준다. 즉, 전략을 쉽게 바꿀 수 있도록 도와주는 디자인 패턴이다.

 

GoF에 따르면, Strategy 패턴의 의도는 다음과 같다.

다양한 알고리즘 군을 정의하고, 이들 각각을 캡슐화하여, 호환성 있게 만든다.

Strategy 패턴은 알고리즘을 이용하는 클라이언트와는 상관없이 독립적으로 이 알고리즘이 변화할 수 있게 해준다.

 

예를 들어, 국제적인 e-tail 시스템에서는 다른 나라의 세금을 계산하기 위해 서로 다른 세금 계산 알고리즘을 사용한다.

 

 

3. 싱글턴 패턴

전역 변수를 사용하지 않고, 객체를 하나만 생성 하도록 하며, 생성된 객체를 어디에서든지 참조할 수 있도록 하는 패턴이다.

 

GoF에 따르면, Singleton 패턴의 의도는 다음과 같다.

한 클래스가 오직 하나의 인스턴스만을 갖도록 하고, 이 인스턴스에 접근할 수 있는 광범위한 지시자(global point) 를 제공한다.

 

아래는 java를 이용한 기본적인 싱글턴 패턴의 소스 코드이다.

class USTax {
  private static USTax instance;
  private USTax() { }
  
  public static USTax getInstance() {
    if(instance == null)
      instance = new USTax();
    
    return instance;
  }
}

하지만 이 코드에서는 한 가지 문제점이 발생한다.

만약 다중 스레드 환경에서 동시에 getInstance() 를 호출한다고 가정해보자. 두 스레드는 동시에 null 을 확인하는데, 이 때 두 스레드는 모두 인스턴스를 생성하지 않았다. 따라서, 두 스레드가 new USTax() 를 수행하게 되어 2개의 인스턴스가 생성된다.

 

이에 대한 해결책으로, synchronized 키워드를 사용한 doSync() 메소드를 활용하는 방법이 있다.

class USTax {
  private static USTax instance;
  private USTax() { }
  
  public synchronized static void doSync() {
    if(instance == null)
      instance = new USTax();
  }
  
  public static USTax getInstance() {
    if(instance == null)
      doSync();
    
    return instance;
  }
}

 

 

4. 옵서버 패턴

한 객체의 상태 변화에 따라 다른 객체의 상태도 연동되도록 일대다 객체 의존 관계를 구성하는 패턴이다. Observer 패턴에서 이벤트를 발생시키고 있는 객체인 Subject는 그 이벤트에 대해 알아야 하는 모든 객체를 예측할 수 가 없다. 따라서 Observer 인터페이스를 생성하고 모든 Observer가 자신을 Subject에 등록하는 책임을 가지도록 요구한다.

 

GoF에 따르면, Observer 패턴의 의도는 다음과 같다.

한 객체의 상태가 변경되면, 이 객체에 의존적인 모든 객체가 통지를 받고 자동으로 수정되게 하기 위해, 객체들 간의 일대다 의존관계를 정의하는 것이다.

 

예를 들어, 차량 연료량 클래스는 연료량이 부족한 경우 연료량에 관심을 가지는 구체적인 클래스(연료량 부족 경고 클래스, 주행 가능 거리 출력 클래스) 에 직접 의존하지 않는 방식으로 이를 통보해야한 다.

 

 

5. 템플릿 메소드 패턴

어떤 작업을 처리하는 일부분을 서브 클래스로 캡슐화하여 전체 일을 수행하는 구조는 바꾸지 않으면서 특정 단계에서 수행하는 내역을 바꾸는 패턴이다. 즉, 전체적으로는 다른 구문으로 구성된 메소드의 코드 죽복을 최소화 할 때 유용하다.

 

GoF에 따르면, Templete Method 패턴의 의도는 다음과 같다.

Operation에 알고리즘의 골격을 정의하고, 이 알고리즘이 가진 몇 가지 단계의 내용은 서브클래스에게 정의를 맡긴다. Templete Method 패턴은 알고리즘의 구조를 변경하지 않으면서 알고리즘의 단계의 내용을 재정의 한다.

 

 

6. 팩토리 메소드 패턴

객체 생성 처리를 서브 클래스로 분리하여 처리하도록 캡슐화하는 패턴이다. 즉, 객체의 생성 코드를 별도의 클래스/메소드로 분리함으로써 객체 생성의 변화에 대비하는 방법이다.

 

GoF에 따르면, Factory Method 패턴의 의도는 다음과 같다.

객체 생성을 위한 인터페이스를 정의하고, 어떤 클래스가 인스턴스화되는지에 대한 결정은 서브클래스가 내리게 한다. Factory Method 패턴은 클래스가 서브클래스에게 인스턴스화에 대한 책임을 전가할 수 있게 해준다.

 

 

 

 

 

'CS > Design Pattern' 카테고리의 다른 글

[DP] 1. 객체 지향 프로그래밍 (OOP)  (0) 2019.04.12