NullObject패턴

이규훈·2025년 2월 12일

Null Object 패턴은 자바를 비롯한 객체지향 프로그래밍에서 null 참조로 인해 발생할 수 있는 문제(예: NullPointerException)를 방지하기 위해 사용되는 디자인 패턴입니다.

핵심 개념

  • 목적:
    일반적으로 메서드를 호출하기 전에 객체가 null인지 매번 확인하는 코드는 가독성을 떨어뜨리고 오류를 유발할 수 있습니다. Null Object 패턴은 “아무런 동작도 하지 않는” 대체 객체를 제공하여, 클라이언트 코드에서 null 체크 없이 동일한 인터페이스로 메서드를 호출할 수 있도록 합니다.
  • 구현 방법:
    1. 인터페이스(또는 추상 클래스) 정의: 해당 협력자의 기능을 정의합니다.
    2. 실제 구현 클래스(Real Object): 정상 동작하는 객체를 구현합니다.
    3. 널 객체(Null Object) 구현: 인터페이스를 구현하되, 메서드 내부에서 아무런 동작도 하지 않거나 기본값(예: false, 0, 빈 문자열 등)을 반환하도록 구현합니다.
    4. 싱글톤 적용: 널 객체는 상태를 갖지 않으므로 여러 인스턴스 대신 하나의 인스턴스를 재사용할 수 있습니다.

이 패턴은 전략 패턴이나 상태 패턴과 유사하게 “아무것도 하지 않는” 구체적인 행동을 제공함으로써 클라이언트가 내부 구현에 신경쓰지 않고 일관된 인터페이스를 사용할 수 있게 합니다.

자바 코드 예제

아래는 고객(Customer)을 처리하는 상황에서 실제 고객과 Null 고객을 구분하여 사용하는 예제입니다.

import java.util.Date;

// 고객 인터페이스 정의
public interface Customer {
    void pay();
    boolean isTimeToPay(Date payDate);
}

// 실제 고객 구현: 정상적인 로직 수행
public class RealCustomer implements Customer {
    @Override
    public void pay() {
        System.out.println("고객 지불 처리 중...");
    }
    
    @Override
    public boolean isTimeToPay(Date payDate) {
        // 실제 결제 시간이 되었는지 판단하는 로직
        return true; // 예시로 항상 true 반환
    }
}

// Null 고객 구현: 아무 동작도 하지 않음 (싱글톤으로 구현 가능)
public class NullCustomer implements Customer {
    private static final NullCustomer instance = new NullCustomer();
    
    private NullCustomer() { }
    
    public static NullCustomer getInstance() {
        return instance;
    }
    
    @Override
    public void pay() {
        // 아무런 동작도 하지 않음
    }
    
    @Override
    public boolean isTimeToPay(Date payDate) {
        return false;
    }
}

이제 데이터베이스 등에서 고객을 찾을 때, 고객이 존재하지 않는 경우에 null 대신 NullCustomer.getInstance()를 반환하도록 하면, 클라이언트 코드에서는 별도의 null 체크 없이 다음과 같이 메서드를 호출할 수 있습니다.

public class PaymentProcessor {
    public void processPayment(String customerName, Date today) {
        // DB에서 고객을 조회하는 메서드가 고객이 없을 경우 NullCustomer를 반환하도록 구현했다고 가정
        Customer customer = DB.getCustomer(customerName); 
        
        // null 체크 없이 바로 메서드 호출 가능!
        if (customer.isTimeToPay(today)) {
            customer.pay();
        }
    }
}

장점과 단점

  • 장점:

    • 클라이언트 코드에서 반복적인 null 체크를 제거하여 코드가 간결해집니다.
    • NullPointerException 발생 위험을 줄입니다.
    • 다형성을 활용해 실제 객체와 널 객체를 동일하게 다룰 수 있습니다.
  • 단점:

    • 잘못 사용할 경우, 실제로 오류가 발생해야 하는 상황도 감춰질 수 있으므로 주의해야 합니다.
    • 추가 클래스를 도입함으로써 시스템 복잡도가 다소 증가할 수 있습니다.

결론

Null Object 패턴은 자바에서 null 체크로 인한 불필요한 복잡성과 오류를 줄이기 위해 매우 유용한 패턴입니다. 객체가 없을 때도 인터페이스의 일관성을 유지함으로써, 클라이언트 코드가 간결해지고 유지보수가 쉬워집니다. 다만, 이 패턴을 도입할 때는 실제로 예외가 발생해야 하는 경우를 놓치지 않도록 주의하는 것이 중요합니다.


참고 자료:
(기계인간 John Grib의 널 오브젝트 패턴 관련 글)

(블랙빈 라이브러리의 널 오브젝트 패턴 설명)

profile
개발취준생

0개의 댓글