본문 바로가기
Programming/DesignPattern

[디자인 패턴] 팩토리(Factory) 메서드 패턴

by Blemish 2021. 5. 31.

 

Goal

  • 팩토리 메서드를 이해한다.

 

팩토리(Factory) 메서드 패턴

 팩토리 메서드 패턴은 객체를 생성하는 코드를 별도의 클래스/메서드로 분리해 캡슐화하는 패턴

 

 팩토리 메서드 패턴은 객체를 생성하는 코드를 별도의 클래스/메서드로 분리함으로써 객체 생성 방식의 변화에 대비하는데 유용하다.
 프로그램이 제공하는 기능은 상황에 따라 언제나 변경될 수 있기 때문에 아래와 같은 문제점이 발생할 수 있다.

  • 기능의 변경이나 상황에 따른 기능의 선택은 바로 해당 객체를 생성하는 코드의 변경을 초래한다.
  • 상황에 따라 적절한 객체를 생성하는 코드는 자주 중복될 수 있다.

 따라서 특정 기능의 구현은 개별 클래스를 통해 제공되는 것이 바람직한 설계이다.

 

클래스 다이어그램

  • Product : 팩토리 메서드에 생성될 객체의 공통 인터페이스
  • ConcreteProduct : 구체적으로 객체가 생성되는 클래스
  • Creator : 팩토리 메서드를 갖는 클래스
  • ConcreteCreator : 팩토리 메서드를 구현하는 클래스로 ConcreteProduct 객체를 생성한다.

 

여러 가지 방식의 엘리베이터 스케줄링 방법 지원하는 기능을 구현해보자.

 

엘리베이터 스케줄링에는 여러가지 전력이 있을 수 있다. 예를 들어 목적지 층과 가까우면서 목적지 층의 방향으로 이동 중인 엘리베이터를 선택하는 것이 하나의 전략이 될 수 있다. 복수의 엘리베이터를 스케줄링해 엘리베이터를 이동시키는 방법을 구현해보자.

클래스 다이어그램

ElevatorManager 클래스는 여러 개의 엘리베이터(ElevatorController)를 갖는다. 또한 스케줄링(ThroughputScheduler) 클래스의 SelectElevator 메서드를 호출해 적절한 엘리베이터를 선택한다. 그리고 선택된 엘리베이터에 해당하는 ElevatorController 객체의 GotoFloor 메서드를 호출해 엘리베이터를 이동시킨다.

※ ThroughputScheduler의 엘리베이터 선택은 임의로 선택한다.

 

Question

  • 기존의 방식 ThroughputScheduler가 아닌 다른 스케줄링 전략을 사용해야 한다면? 
  • 프로그램 실행 중에 스케줄링 전략을 변경, 즉 동적 스케줄링을 지원해야 한다면? 예를 들어 오전에는 대기 시간을 최소화 전략을 사용하고, 오후에는 처리량 최대화 전략을 사용해야 한다면?

 -> ElevatorManager 클래스를 수정해야 함. 즉, OCP에 위배

 

위의 질문처럼 다른 스케줄링 전략을 추가하고 동적 스케줄링을 지원하도록 구현해보자.

 

클래스 다이어그램

 

 전략 패턴을 활용하여 스케줄링 기법을 추가하였다. 따라서 새로운 스케줄링이 추가될 때마다 ElevatorScheduler 인터페이스를 참조하면 된다. 하지만 새로운 스케줄링이 추가되면 RequestElevator는 계속해서 변경해줘야 한다.   RequestElevator 메서드는 엘리베이터 선택과 선택된 엘리베이터를 이동시키는 것이 근본 책임이다. 그러므로 엘리베이터를 선택하는 전략의 변경에 따라 RequestElevator가 변경되는 것은 바람직하지 않다.

 이러한 문제점을 해결하려면 주어진 기능을 실제로 제공하는 적절한 클래스 생성 작업을 별도의 클래스/메서드로 분리시키는 편이 좋다.

클래스 다이어그램

ElevatorFactory 클래스를 구현하여서 스케줄링 전략에 일치하는 클래스를 생성하는 코드를 작성하였다.

이로써 RequestElevator 메서드는 엘리베이터 선택과 선택된 엘리베이터를 이동시키는 기능만 책임지게 되었다.

댓글