ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 방어적 프로그래밍 - 널 객체 패턴 사용해보기
    개발/디자인패턴 2023. 9. 18. 10:10

    여러 언어에서 NULL(혹은 nil) 은 어떤 키에 값이 존재하지 않는다는 뜻으로 사용한다. 이 비어있는 키에 NULL 검사 외의 다른 방법으로 접근하려고 하면, 대부분 Null Pointer Exception 을 던진다.

     

    NULL 을 포함한 객체를 생성하고 전달하면 항상 NULL을 참조하는 예외가 발생할 수 있다.

    조심하면 된다. 쓰기전에 검사하면 된다 라고 할 수 있지만 설계에 조금만 신경쓰면 예방할 수 있는 방법이 있으니 이 방법을 활용해보자.

     

    언어는 타입스크립트로 작성했다.

     

    export class Inventory {
      ...
      getItemQuantity(itemNumber: number) {
        return this.getItem(itemNumber).getAmount();
      }
      ...
      protected getItem(itemNumber: number) {
        if (this.hasItem(itemCode)) return this.items[itemCode];
        else return new Item(itemCode);
      }
      ...
    }
    
    
    class Item {
      constructor(itemNumber: number) {
        this.itemCode = itemCode;
        this.amount = 0;
      }
      ...
    }

     

    인벤토리와, 그 안에 있는 아이템에 대한 객체다. 인벤토리에서 아이템 번호로 아이템을 찾아 그 수량을 얻어내는 코드이다. 인벤토리에서 아이템을 선택하는 getItem 이라는 메소드를 보면, 아이템 번호로 아이템 유무를 확인하고, 있으면 아이템을 반환하고 없으면 새 아이템을 생성해서 반환한다.

     

    새 아이템을 생성하는 코드를 보면 수량이 0인 아이템을 반환하도록 하고 있다.

     

    만약, 아이템이 없으면 null을 반환하고 null일때의 처리를 별도로 구성한다면, 널 포인터 예외는 당연히 발생할 수 있고 논리 구조가 복잡해진다. 두 논리 구조를 비교해보자.

     

    1. NULL 객체 패턴을 적용한 논리구조

    a. 아이템을 선택한다.

    b. 선택한 아이템의 수량을 반환한다.

     

    2. NULL을 반환하는 논리구조

    a. 아이템을 선택한다.

    b. 선택한 아이템의 반환이 null인지 확인한다.

    c. null이면 0을 반환한다.

    d. null이 아니라면 선택한 아이템의 수량을 반환한다.

     

     

    단순한 수량 반환만 해도 논리가 간단해진다. 인벤토리에 아이템을 추가하기 같은 기능 확장을 위한 논리도 단순해질것이라는 상상을 해보자. 물론 항상 나오는 이야기인 은 총알은 세상에 존재하지 않는 만큼 이런 방법론은 예외나 에러를 발생해야 할 상황을 놓친다면, 추후에 찾아내기 어려워진다는 단점이 있다. 하지만, 우리에겐 테스트코드가 있지 않은가.

     

    여기서, 인벤토리와 아이템이 아니면 적용하기 힘든 구조가 아닌가 라는 생각이 잠깐 들 수 있지만

    게시판과 게시글, 회원 관리 시스템에서의 회원, IoT 시스템의 센서 등등.. 여러 체계가 인벤토리와 아이템과 굉장히 비슷하다는것을 알 수 있다. 널 객체 패턴의 여러 예시는 직원 관리 시스템을 예시로 들고 있는데 적절한 추상화를 해보면 인벤토리와 아이템과 크게 다르지 않다고도 볼 수 있지 않을까.

     

Designed by Tistory.