티스토리 뷰

‘개발자가 반드시 정복해야 할 객체 지향과 디자인 패턴' 책을 보고 정리한 글입니다.

 

장기 고객 할인으라든가 신규 고객 할인과 같이 고객의 상태에 따라 특별 할인을 해준다고 가정해보자.

사용 요금 명세서를 생성하는 기능은 아래 코드와 같이 명세서 상세 내역에 특별 할인 기능을 추가할 수 있다.

public Bill createBill(Customer customer) {
    Bill bill = new Bill();
    
    // 사용 내역 추가
    bill.addItem(new Item("기본사용요금", price));
    bill.addItem(new Item("할부금", somePrice));
    
    // 특별 할인 내역 추가
    SpecialDiscount specialDiscount = specialDiscountFactory.create(customer);
    if(specialDiscount != null) { // 특별 할인 대상인 경우만 처리
        specialDiscount.addDetailTo(bill);
    }
    return bill;
}

고객에 따라 특별 할인이 없는 경우도 있기 때문에, 위 코드에서는 null 체크를 하여 특별 할인 내역을 추가하도록 했다.

null 검사 코드를 사용할 때의 단점은 개발자가 null 검사 코드를 빼 먹기 쉽다는 점이다.

여러 코드에서 한 객체에 대한 null 검사를 하게 되면 null 검사 코드를 누락하기 쉬우며, 이는 프로그램 실행 도중에 NullPointerException을 발생시킬 가능성을 높여준다.

 

널 객체 패턴은 null 검사 코드 누락에 따른 문제를 없애 준다.

널 객체 패턴은 null을 리턴하지 않고 null을 대신할 객체를 리턴함으로써 null 검사 코드를 없앨 수 있다.

  • null 대신 사용될 클래스를 구현한다.
    • 이 클래스는 상위 타입을 상속받으며, 아무 기능도 수행하지 않는다.
  • null을 리턴하는 대신, null을 대체할 클래스의 객체를 리턴한다.

 

SpecialDiscount 객체가 null일 때 대신 사용될 클래스를 다음과 같이 구현한다.

public class NullSpecialDiscount extends SpecialDiscount {
    @Override
    public void addDetailTo(Bill bill) {
        // 아무것도 하지 않음
    }
}

SpecialDiscount 객체를 생성하는 코드는 이제 null을 리턴하는 대신 NullSpecialDiscount 객체를 리턴하도록 수정한다.

public class SpecialDiscountFactory {
    
    public SpecialDisCount create(Customer customer) {
        if (checkNewCustomer(customer)) {
            return new NewCustomerSpecialDiscount();
        }
        // 다른 코드 실행
        
        // 특별 할인 혜택이 없을 때, null 대신 NullSpecialDiscount 객체 리턴
        return new NullSpecialDiscount();
    }
}

이제 위 메서드를 이용해서 특별 할인 내역을 처리한느 코드는 아래처럼 바뀐다.

public Bill createBill(Customer customer) {
    Bill bill = new Bill();

    // 사용 내역 추가

    // 특별 할인 내역 추가
    SpecialDiscount specialDiscount = specialDiscountFactory.create(customer);
    
    // 이제 null 검사가 불필요
    specialDiscount.addDetailTo(bill);
        
    return bill;
}

널 객체 패턴의 장점은 null 검사 코드를 사용할 필요가 없기 때문에 코드가 간결해진다.

이에 따라 코드 가독성이 높아지므로, 향후에 코드 수정을 보다 쉽게 만들어 준다.

'JAVA > 디자인 패턴' 카테고리의 다른 글

어댑터 패턴  (0) 2022.03.09
Iterator 패턴  (0) 2022.03.08
컴포지트(Composite) 패턴  (0) 2022.03.06
추상 팩토리(Abstract Factory) 패턴  (0) 2022.03.06
파사드(Facade) 패턴  (0) 2022.03.05
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함