본문 바로가기

Java

Optional

체스를 구현하던중 Optional 에 대해서 알게 되었다.

 

Optional 의 등장배경


Optional 은 null 로 인해 발생하는 문제 때문에 등장하게 되었다.

메서드의 반환값으로 null 이 반환될 수 있고, 때문에 에러가 발생될 가능성이 높은 상황이라면 사용하자는 취지이다.

 

 

백문이 불여일견

코드로 살펴보자.

 

Optional 적용 전


체스의 메소드 중 체스판의 좌표(Position)에 해당하는 체스말(Piece)을 찾는 메소드가 있었다.

1
2
3
4
5
6
public Piece findPieceByPosition(Position position) {
   return pieces.stream()
         .filter(x -> x.isEqualPosition(position))
         .findAny()
         .orElse(null);
}

 

그리고 아래의 코드는 체스말을 이동시킬 때 목적지점에 같은팀 체스말이 있는지 확인하는 코드이다.

1
2
3
4
5
6
7
8
9
10
11
private void validateTargetTeam(Position sourcePosition, Position targetPosition) {
   Piece sourcePiece = findPieceByPosition(sourcePosition);
   Piece targetPiece = findPieceByPosition(targetPosition);
   
   if (targetPiece != null){
      return;
   }
   if (sourcePice.isSameTeam(targetPiece) {
      throw new IllegalArgumentException("해당 칸에 같은 팀의 말이 존재 합니다");
   }
}
 

 

위의 코드를 살펴보면 sourcePiece 가 null 일때 NullPointException이 발생된다.

실수로 sourcePiece가 null 일 때의 처리를 누락한것이다.

그리고 누구나 이런 실수를 범한적이 있을 것이다.

또한 매번 null 체크를 해주다보면 코드가 지저분해지는 경우도 있다.

 

 

이런 상황에서 Optional 을 사용할 수 있다.

 

Optional 적용 후


 

먼저 좌표로 체스말을 찾는 메소드는 다음과 같다.

1
2
3
4
5
public Optional<Piece> findPieceByPosition(Position position) {
   return pieces.stream()
         .filter(x -> x.isEqualPosition(position))
         .findAny();
}
 

 

반환형은 Optional<Piece>이다.

만약 입력한 좌표에 체스말이 있다면 체스말이 값으로 들어있는 Optional 객체가 반환된다.

반대로 입력한 좌표에 체스말이 없다면 값이 없는 텅빈 Optional 객체가 반환된다.

 

그렇다면 이를 이용한 메소드들은 어떻게 리펙토링 될 수 있을까?

 

다음은 목적지점에 있는 체스말의 팀을 체크하는 메소드를 리펙토링한 것이다.

1
2
3
4
5
6
7
8
9
10
private void validateTargetTeam(Position sourcePosition, Position targetPosition) {
    Piece sourcePiece = findPieceByPosition(sourcePosition)
        .orElseThorw(() -> new IllegalArgumentException("해당 칸에 움직일 말이 없습니다"));
    
    findPieceByPosition(targetPosition)
        .filter(target -> sourcePiece.isSameTeam(target))
        .ifPresent(piece -> {
            throw new IllegalArgumentException("해당 칸에 같은 팀의 말이 존재 합니다")
        });
}

 

위 코드의 특징으로는 먼저 null 체크를 하는 조건문이 없다.

그리고 Optional 사용 전에는 실수로 sourcePiece의 null 체크를 놓쳤지만 여기에서는 NullPointException 이 발생할 일이 없다.

코드도 깔끔해져 가독성이 높아진것 같다.

 

 

정리


이처럼 null 이 발생할 가능성이 있는 부분에서 Optional 을 사용해주니 여러가지고 장점이 많은 것 같다.

귀찮은 null 체크도 안해도 되고,

그러다 보니 실수가 줄고,

코드도 깔끔해지니 여러가지로 유용하다.

반응형