이 영역을 누르면 첫 페이지로 이동
Arc 블로그의 첫 페이지로 이동

Arc

페이지 맨 위로 올라가기

Arc

[OOP] 무분별한 Getter/Setter를 지양하라

  • 2023.03.16 00:33
  • Software Engineering/OOP
글 작성자: SeoArc

무분별한 Getter/Setter를 지양하라?

우리는 보통 개발을 할 때 getter와 setter 메서드를 생성하여 자주 사용하곤한다. 그리고 매우 편리하다. 하지만 이렇게 모든 멤버변수에 대해 getter/setter를 생성하여 사용하는 것이 좋을까?

객체지향 설계 시에 이를 지양하는 것이 좋다고 한다. 왜 그럴까?

 

 

Setter를 지양하라?

개발은 혼자가 아니다

setter를 무분별하게 사용하면 다른 개발자가 해당 코드를 봤을 때 값을 변경한 의도를 파악하기 힘들어진다.

public static void main(String[] args) {
    Lotto lotto = new Lotto(List.of(1, 4, 12, 32, 40, 41));
    lotto.setNumbers(List.of(13, 14, 20, 31, 36, 45));
}

위 코드를 보면 Lotto를 생성한 후 setter메서드를 통해 번호를 다시 부여한 것을 확인할 수 있다. 하지만 이렇게 setter를 통해 값을 넣으면 어떤 의도로 넣은 것인지 명확히 알 수 없다.

 

 

객체의 일관성을 유지하자

setter를 사용하면 언제든 외부에서 객체 상태를 바꿀 수 있게 된다. 예시로, 위에서 본 코드처럼 얼마든 Lotto가 가지고 있는 번호들을 바꿀 수 있게 된다. 이렇게 되면 객체의 일관성을 유지하기 힘들어지고 어디서 어떤 상태가 변경되는지 파악하기 힘들어진다. 즉, 코드의 가독성이 떨어질 수 있다.

 

 

Getter를 지양하라?

각자의 책임을 지게하자

객체는 각자 알맞는 행동과 책임을 갖고 있으며, 객체의 상태는 캡슐화되어 외부에 노출시키지 않는다. 또 객체는 다른 객체와 메시지를 주고 받으며 협력한다. 객체는 메시지를 받으면 그에 따른 행동(로직)을 수행하게 되고, 필요하다면 객체 스스로 내부의 상태(값)도 변경한다.

 

그런데 모든 멤버변수에 getter를 생성해놓고 상태 값을 꺼내 그 값으로 객체 외부에서 행동한다면, 그 객체의 책임이 다른 곳에서 수행되고 외부에서 상태를 변경하는 상황이 생길 수 있다.

객체는 각자 책임을 가지고 행동을 수행하며 서로 메시지를 통해 협력해나가는 관계여야한다. 하지만 위와 같은 형태는 객체 간의 협력이라고 보기 힘들다.

 

또한 getter를 무분별하게 사용하면 "메시지 체인"이라는 악취가 나게 된다.

메시지 체인이란, 다음과 같이 레퍼런스를 따라 계속해서 메서드 호출이 이어지는 코드를 말한다.

object.getChild().getContent().getItem().getTitle();

이렇게 되면 코드의 가독성도 떨어지는 효과도 볼 수 있다.

 

다음은 로또 번호를 비교하는 코드 예시이다.

class Lotto {
    private List<Integer> numbers;
    
    public Lotto(List<Integer> numbers) {
        this.numbers = new ArrayList(numbers);
    }
    
    public int getNumber(int index) {
        return numbers.get(index);
    }
}

public class Client {
    private static final int LOTTO_NUMBER_LENGTH = 6;
    
    public static void main(String[] args) {
        Lotto lotto = new Lotto(List.of(3, 7, 15, 21, 25, 41));
        
        boolean exist = false;
        for (int i = 0; i < LOTTO_NUMBER_LENGTH; i++) {
            if (lotto.getNumber(i) == 15) {
                exist = true;
                break;
            }
        }
    }
}

위 로직을 보면 lotto에서 getter로 값을 꺼내 비교하는 것을 볼 수 있다. 하지만 여기서 두 번호를 비교하는 로직을 수행하는 것이 맞을까?

위에서 말했듯이 객체는 각자 스스로 알맞은 책임을 가지고 행동해야 한다.

 

하지만 위 로직은 값을 판단하는 책임이 Lotto가 가지고 있는게 아닌 외부에 있다. 이를 Lotto 내부로 옮겨 Lotto가 해당 값이 포함되어 있는지 체크하도록 해보자.

class Lotto {
    private List<Integer> numbers;
    
    public Lotto(List<Integer> numbers) {
        this.numbers = new ArrayList(numbers);
    }
    
    public boolean contains(int number) {
        return numbers.contains(number);
    }
}

public class Client {
    private static final int LOTTO_NUMBER_LENGTH = 6;
    
    public static void main(String[] args) {
        Lotto lotto = new Lotto(List.of(3, 7, 15, 21, 25, 41));
        
        boolean exist = lotto.contains(15);
    }
}

이렇게 해서 외부에서는 해당 값이 들어있는지 메시지를 보내고 Lotto는 포함되어 있는지 여부를 반환하도록 했다. 이렇게 함으로써 좀 더 객체스러운 코드가 됐다.

 

마무리

getter를 무조건 사용하지 말라는 것이 아니다. 당연히 getter를 쓰지 않고 구현하기 힘든 것이 있을 것이다. 예를 들어, 출력이나 데이터를 이동하기 위해 쓰는 DTO 등에서는 사용이 어느 정도 허용된다. 하지만 위에서와 같이 너무 무분별한 사용을 피하고 되도록 객체의 책임을 부여하고 메시지를 통해 협력하고 행동할 수 있도록 설계하는 자바 개발자가 되어보자.

'Software Engineering > OOP' 카테고리의 다른 글

[OOP] 원시 타입을 포장하라  (0) 2023.03.15
[OOP] 상속보다는 조합을 사용하자  (0) 2023.03.15
[OOP] instanceof의 사용을 지양하라  (0) 2023.03.14

댓글

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • [OOP] 원시 타입을 포장하라

    [OOP] 원시 타입을 포장하라

    2023.03.15
  • [OOP] 상속보다는 조합을 사용하자

    [OOP] 상속보다는 조합을 사용하자

    2023.03.15
  • [OOP] instanceof의 사용을 지양하라

    [OOP] instanceof의 사용을 지양하라

    2023.03.14
다른 글 더 둘러보기

정보

Arc 블로그의 첫 페이지로 이동

Arc

  • Arc의 첫 페이지로 이동

검색

메뉴

  • 홈
  • 태그
  • 방명록

카테고리

  • 분류 전체보기 (106)
    • Language (28)
      • C++ (0)
      • C# (0)
      • Java (28)
    • Algorithm (47)
      • Algorithm (15)
      • Data Structure (6)
      • PS (26)
    • Computer Science (22)
      • Design Pattern (1)
      • Network (14)
      • OS (7)
    • Game (0)
      • Unity (0)
    • Backend (3)
      • Spring (1)
      • JPA (2)
    • DB (0)
      • SQL (0)
    • DevOps (2)
      • AWS (0)
      • Docker (2)
      • Jenkins (0)
      • Nginx (0)
    • Software Engineering (4)
      • OOP (4)
    • AI (0)
      • Machine Learning (0)
    • Others (0)

최근 글

인기 글

댓글

공지사항

아카이브

태그

  • java
  • graph
  • 네트워크
  • 그래프
  • 알고리즘
  • 자바
  • algorithm
  • network

나의 외부 링크

정보

SeoArc의 Arc

Arc

SeoArc

블로그 구독하기

  • 구독하기
  • RSS 피드

방문자

  • 전체 방문자
  • 오늘
  • 어제

티스토리

  • 티스토리 홈
  • 이 블로그 관리하기
  • 글쓰기
Powered by Tistory / Kakao. © SeoArc. Designed by Fraccino.

티스토리툴바