Easy Understanding

웹 백엔드 관점으로 본 디자인 패턴 정리(10) - 반복자, 컴포지트, 상태 패턴(Iterator, Composite, State Pattern) 본문

Study

웹 백엔드 관점으로 본 디자인 패턴 정리(10) - 반복자, 컴포지트, 상태 패턴(Iterator, Composite, State Pattern)

appleg1226 2022. 5. 8. 18:56

 

이번엔 3가지 패턴을 한 번에 정리한다.

생각보다 간단하고 활용성이 클 것 같지 않아서 정리하다보니 내용이 짧아졌고 그래서 합치게 되었다.

반복자 패턴

- 필요 개념: 컬렉션
- 활용도:필요하다면..
- 난이도: 간단
- 패턴이 필요한 상황: 컬렉션을 통합적으로 사용할 필요가 있을 때

 

모든 언어에는 여러 컬렉션이 존재한다.

자바의 경우는 다음과 같은 것이 대표적이다.

List<String> list;
String[] arr;
Map<String, String> map;
Set<String> set;

그런데 여러 컬렉션들을 사용할 때 클라이언트에서는 이걸 같은 코드로 사용하고 싶을 때가 있다.

 

다양한 인터페이스 구현체들을 사용할 때 세부 구현체를 몰라도 되는 것처럼,

컬렉션도 비슷하게 처리할 수 있으면 좋은데, 그 대표적인 명세가 바로 Iterator 이다.

 

사실 자바에는 이미 Iterator 인터페이스가 내장되어 있고,

대부분의 컬렉션들이 이 Iterator로의 변환을 제공하기 때문에 크게 배워야 할 지식은 적은 것 같다.

가끔 Custom Iterator를 만들고 싶다면, 검색을 해서 참고하며 만들어보자.

 


컴포지트 패턴

- 필요 개념: 트리의 순회 알고리즘
- 활용도:상황이 발생할 경우가 많지는 않다.
- 난이도: dfs 알고리즘을 알면 좋다.
- 패턴이 필요한 상황: 트리 형태의 객체 목록을 순회해야 할 때

 

트리 형태의 자료구조를 만든다는 것은 아래와 같은 그림과 같은 경우라고 보면 된다.

어떤 객체에 하위 컬렉션들이 있고, 그것이 또 다른 하위 컬렉션들을 갖게될 경우다.

 

https://refactoring.guru/design-patterns/composite

 

트리구조는 데이터베이스 내부적으로 인덱스를 구현할 때나 많은 경우에 사용되지만,

실제 비즈니스 로직에서는 대부분은 List 형식의 데이터가 많고 트리 구조라고 하더라도 순회해야 할 일은 많지 않다.

 

트리 알고리즘 문제를 풀다보면 여러 순회에 대한 문제들이 있고 방법도 다양해서 참고하면 도움이 될 듯 하다.

 


상태 패턴

- 필요 개념: 상속
- 활용도:API를 제공하는 서비스에서는 크게 필요하진 않음
- 난이도: 좀 들여다봐야 이해됨
- 패턴이 필요한 상황: State가 메인 로직인 프로그램 작성시

 

헤드 퍼스트에서는 이 패턴의 예시를 뽑기 기계로 설명한다.

뽑기 기계는 여러 상태를 가지는데

- 돈을 넣은 상태

- 돈이 없는 상태

- 뽑기 머신을 돌리기 전 상태

- 뽑기 머신을 돌린 이후 상태

이외에도 머신에는 여러 상태가 존재한다.

 

한 메서드의 예시인데 상태에 따라서 다른 결과 값을 내야한다.

public void insertQuater(){
  if(돈을 넣은 상태){
  
  } else if(돈을 넣지 않은 상태){
  
  } else if(돌리기 전 상태){
  
  } else {
  
  }
}

 

이말인 즉 클래스 내부에 상태가 존재한다는 것이다.

public class GambleMachine {
  MachineStatus status;
  
  public void insertQuater(){
    ... 
  }
}

 

이건 다양한 유저의 웹 요청을 처리하는 프로그램에선 별로 나타날 수가 없는 패턴이다.

일단 백엔드 API에서는 사용할 일은 크게 없을 것 같다.

딱 봐도 '하나의 상태를 관리한다?'

동시성 문제부터 머리가 아플듯하다.

 

Stateful 한 어플리케이션이라면 특정 어플리케이션의 개인 셋팅에 사용해보지 않을 수 있지 않을까 싶다.

이외에는 모든 클라이언트가 공유해야 하는 하나의 데이터가 있다던지 하는 경우일텐데

별로 많지는 않을 것이다.

 

상태패턴이 쓸일이 많지가 않을 뿐이지, 의외로 패턴 자체는 강력하다.

 

만약 Stateful 한 상황에 직면한 코드를 만들 때, if else가 늘어져 있는 냄새나는 코드가 많다면

상태 패턴은 이런 문제를 아주 깔끔하고 유연하게 처리해 준다는 특장점이 있다.

 

정말 적겠지만 특정 Lifecycle이 필요한 어플리케이션이 있다면

한번 적용해보면 재미있을 것 같은 패턴이다.