[행위 패턴] Null Object pattern (널 오브젝트 패턴)

 

Null의 행위를 정의한 객체이다.

 

(원본 출처 : https://www.tutorialspoint.com/design_pattern/design_pattern_quick_guide.htm)

 

Null Object 패턴에서 NULL 객체는 NULL 객체 인스턴스의 검사를 대체합니다. null 값을 검사하는 경우, Null Object는 do nothing 관계를 반영합니다. 이러한 Null 객체는 데이터를 사용할 수없는 경우를 대비하여 기본 동작을 제공하는 데 사용될 수도 있습니다.

 

Null Object 패턴에서는 수행 할 다양한 연산을 지정하는 abstract 클래스를 만들고,이 클래스를 확장하는 클래스와이 클래스를 구현하지 않는 null 객체 클래스를 구체화하며 null 값을 확인할 필요가없는 곳에서는 아무렇지도 않게 사용됩니다.

 

Implementation

우리는 Opearations를 정의하는 AbstractCustomer 추상 클래스를 만들 것입니다. 여기에는 고객 이름과 AbstractCustomer 클래스를 확장하는 구체적인 클래스가 있습니다. Factory 클래스 CustomerFactory는 전달 된 고객의 이름을 기반으로 RealCustomer 또는 NullCustomer 객체를 반환합니다.

NullPatternDemo, 우리 데모 클래스는 CustomerFactory를 사용하여 Null Object 패턴의 사용법을 보여줍니다.

Null Object Pattern UML Diagram

Step 1

추상클래스를 생성합니다.

AbstractCustomer.java

public abstract class AbstractCustomer {
   protected String name;
   public abstract boolean isNil();
   public abstract String getName();
}

Step 2

위의 클래스를 확장하는 구체적인 클래스를 만듭니다.

RealCustomer.java

public class RealCustomer extends AbstractCustomer {

   public RealCustomer(String name) {
      this.name = name;		
   }
   
   @Override
   public String getName() {
      return name;
   }
   
   @Override
   public boolean isNil() {
      return false;
   }
}

NullCustomer.java

public class NullCustomer extends AbstractCustomer {

   @Override
   public String getName() {
      return "Not Available in Customer Database";
   }

   @Override
   public boolean isNil() {
      return true;
   }
}

Step 3

CustomerFactory 클래스를 생성합니다.

CustomerFactory.java

public class CustomerFactory {
	
   public static final String[] names = {"Rob", "Joe", "Julie"};

   public static AbstractCustomer getCustomer(String name){
      for (int i = 0; i < names.length; i++) {
         if (names[i].equalsIgnoreCase(name)){
            return new RealCustomer(name);
         }
      }
      return new NullCustomer();
   }
}

Step 4

CustomerFactory를 사용하여 전달 된 고객의 이름에 따라 RealCustomer 또는 NullCustomer 객체를 가져옵니다.

NullPatternDemo.java

public class NullPatternDemo {
   public static void main(String[] args) {

      AbstractCustomer customer1 = CustomerFactory.getCustomer("Rob");
      AbstractCustomer customer2 = CustomerFactory.getCustomer("Bob");
      AbstractCustomer customer3 = CustomerFactory.getCustomer("Julie");
      AbstractCustomer customer4 = CustomerFactory.getCustomer("Laura");

      System.out.println("Customers");
      System.out.println(customer1.getName());
      System.out.println(customer2.getName());
      System.out.println(customer3.getName());
      System.out.println(customer4.getName());
   }
}

Step 5

결과를 확인합니다.

Customers
Rob
Not Available in Customer Database
Julie
Not Available in Customer Database

 

 

장점 

  • 수많은 널 검사 로직 없이도 널 값으로 인한 에러를 막을 수 있다.
  • 널 검사 로직이 최소화되어 코드가 간단해진다.

단점

  • 프로그래머가 널 객체의 존재를 모르고 있다면, 동일한 널 검사를 불필요하게 여러번 하게 될 수 있다.
  • 유지보수가 복잡해진다. 널 객체의 수퍼클래스에 새 public 메소드를 추가할 때마다 널 객체 클래스에서 이를 오버라이드해야 한다.

 

다른 패턴과의 관계

 

  • Null Object 패턴은 전략패턴이나 상태패턴의 특수한 경우로 볼 수 있다.

 

결론

  • C 기반 언어를 오래 사용해온 사람들은 어떤 종류의 실패에 대해 null이나 0을 반환하는 함수에 익숙하다.
  • 이들은 이런 함수의 반환값은 검사되어야 할 필요가 있다고 생각한다.
  • 그러나 NULL OBJECT 패턴은 다르다.
  • 이 패턴을 사용하면, 우리는 함수가 실패한 경우에도 항상 유효한 객체를 반환한다는 것을 보장할 수 있다.
  • 실패를 나타내는 객체들은 '아무일도' 하지 않는다.

     

    Posted by kunoo
    ,