WIPIVERSE

널 오브젝트 패턴

널 오브젝트 패턴(Null Object Pattern)은 객체 지향 컴퓨터 프로그래밍에서 사용되는 디자인 패턴의 하나로, 참조된 값이 없거나 정의된 중립(널) 동작을 가진 객체를 의미하는 "널 객체"의 사용법과 그 동작을 설명하는 패턴이다. 이 패턴은 1996년 토마스 퀴네(Thomas Kühne)가 "Void Value"라는 이름으로 처음 출판하였고, 이후 1998년 바비 울프(Bobby Woolf)가 《Pattern Languages of Program Design 3》 서적 시리즈에서 "Null Object"라는 이름으로 출판하면서 널리 알려졌다.

개념

대부분의 객체 지향 언어에서 참조(reference)는 널(null)일 수 있다. 메서드는 일반적으로 널 참조에 대해 호출될 수 없으므로, 어떤 메서드를 호출하기 전에 해당 참조가 널이 아닌지 확인해야 한다. 널 오브젝트 패턴은 객체의 부재(예를 들어, 존재하지 않는 고객)를 전달하기 위해 널 참조를 사용하는 대신, 예상되는 인터페이스를 구현하지만 메서드 본문이 비어 있는 객체를 사용하는 기법이다.

널 객체 사용의 주요 목적은 다양한 종류의 조건문(특히 널 검사)을 피하여 코드를 더 집중적이고 읽고 따르기 쉽게 만드는 것, 즉 가독성을 향상시키는 것이다. 널 객체는 매우 예측 가능하고 부작용이 없다는 장점이 있다. 예를 들어, 함수가 폴더의 파일 목록을 검색하고 각 파일에 대해 어떤 작업을 수행하는 상황에서, 빈 폴더의 경우 널 참조 대신 빈 목록(널 객체)을 반환함으로써 호출 함수는 반환 값이 실제로 목록인지 확인할 필요가 없어진다.

다른 패턴과의 관계

널 오브젝트 패턴은 상태 패턴(State Pattern) 및 전략 패턴(Strategy Pattern)의 특수 사례로 간주될 수 있다. 이 패턴은 《디자인 패턴》(GoF) 책에 수록된 패턴은 아니지만, 마틴 파울러(Martin Fowler)의 《Refactoring》과 조슈아 케리에브스키(Joshua Kerievsky)의 《Refactoring To Patterns》에서 "Insert Null Object" 리팩토링으로 언급된다. 또한 로버트 C. 마틴(Robert C. Martin)의 《Agile Software Development: Principles, Patterns and Practices》 17장이 이 패턴에 전념하고 있다.

구현 방식

널 오브젝트 패턴은 다양한 프로그래밍 언어에서 구현될 수 있다. Java, C#, C++ 등 정적 타입 언어에서는 인터페이스나 추상 클래스를 구현하는 별도의 널 클래스를 만들어 사용한다. 예를 들어, Animal 인터페이스가 있을 때 Dog 클래스와 함께 NullAnimal 클래스를 만들어 makeSound() 메서드의 본문을 비워 두는 방식이다. 이때 널 클래스는 널 객체가 필요한 각 클래스 계층에 대해 별도로 생성되어야 한다.

덕 타이핑(duck typing)을 지원하는 언어인 Ruby나 JavaScript에서는 언어 상속이 필요하지 않으며, 예상되는 동작을 제공하는 널 객체를 직접 정의하여 사용할 수 있다. Smalltalk에서는 모든 것이 객체이며, 객체의 부재는 nil이라는 객체로 모델링된다. Common Lisp에서는 nil이 특수 클래스 null의 유일한 인스턴스로, 객체 시스템에 널 디자인 패턴이 본질적으로 내장되어 있다.

대안

C# 6.0부터는 널 조건부 연산자("?.")를 사용할 수 있으며, 이는 왼쪽 피연산자가 널이면 단순히 널로 평가된다. 또한 일부 .NET 언어에서는 확장 메서드와 널 병합 연산자를 사용하여 널 값을 안전하게 처리할 수 있다. 널 오브젝트 패턴과 관련된 개념으로는 널러블 타입(Nullable Type)과 옵션 타입(Option Type)이 있다.

비판

이 패턴은 오류나 버그가 정상적인 프로그램 실행처럼 보이게 만들 수 있으므로 신중하게 사용해야 한다는 비판이 있다. 널 검사를 피하고 코드를 더 읽기 쉽게 만들려는 목적으로만 이 패턴을 구현하는 것은 지양해야 하며, 제공된 객체가 실제로 널 객체인 경우 다른 로직이 실행되어야 하는 상황에서는 주의가 필요하다. 또한 대부분의 언어에서 널 객체가 싱글턴 패턴을 구현하지 않는 경우, 널 값 대신 널 객체를 확인하는 것은 오버헤드를 발생시킬 수 있다.

둘러보기

더 찾아볼 만한 주제

    전체 문서 보기