독서이야기/엘레강트 오브젝트 - 새로운 관점에서 바라본 객체지향

[엘레강트 오브젝트] 3.5 절대 getter와 setter를 사용하지 마세요

사랑꾼이야 2023. 3. 22. 23:41
반응형

이 내용은 엘레강트 오브젝트 를 읽으면서 정리한 내용을 포함하고 있습니다.

  • getter와 setter
  • 정리
  • 관련해서 생각해볼 내용

getter와 setter

getter와 setter의 형태는 다음과 같다.

class Cash {
    private int dollars;

    public int getDollars() {
        return this.dollars;
    }

    public void setDollars(int value) {
        this.dollars = value;
    }
}
  • 위 클래스는 다음과 같은 문제점이 있다.
    • 이 클래스는 가변이고, 두 개의 메서드는 이름이 잘못 지어졌고, 생성자도 없다.
    • 가변성, 메서드 이름, 생성자가 하나도 없다는 사실보다 더 큰 문제는 해당 클래스는 단순한 자료구조이다.

객체 대 자료구조

자료구조

  • 멤버 필드에 직접 접근
  • 단순한 데이터 모음

클래스

  • 멤버 필드에게 접근하는 것을 허용하지 않음
  • 자신의 멤버 필드를 노출하지 않음
  • 클래스 안에 멤버 필드가 있는지조차 알 수 없음
차이점 자료구조 객체
1 투명 불투명
2 글래스 박스 블랙 박스
3 수동적 능동적
4 죽어있음 살아 있음

캡슐화

자료구조보다 클래스를 사용하는 이유는 캡슐화이다.

  • 캡슐화는 OOP가 지향하는 가장 중요한 설계 원칙 중 하나
  • 데이터는 객체 안에 캡슐화되어 있고, 객체는 살아 있다.
  • 객체들은 서로 연결되고, 어떤 일을 수행해야 할 때는 메시지를 전송해서 작업을 실행한다.
  • 메시지를 통한 코드의 실행을 메서드 호출이라고 부른다.
  • 객체가 일급 시민이며, 생성자를 통한 객체 초기화가 곧 소프트웨어이다.
    • 소프트웨어는 연산자나 구문이 아닌 생성자를 통해 구성된다.

객체지향적이고 선언형 스타일을 유지하기 위해서는, 데이터를 객체 안에 감추고 절대로 외부에 노출해서는 안된다. 정확하게 무엇을 캡슐화하고 있고, 자료구조가 얼마나 복잡한 지는 오직 객체만이 알고 있어야 합니다.

좋은 의도, 나쁜 결과

근본적으로 getter와 setter는 캡슐화 원칙을 위반하기 위해 설계되었다.

class Cash {
    public int dollars;
}
  • 이 방식은 Java 프로그래밍의 기본 규칙을 심각하게 위반
  • 작성한 프로그래머가 OOP를 제대로 이해하지 못했다고 생각할 것

이런 상황을 해결하기 위한 방법으로는 다음과 같다.

  • 접근제어자를 private으로 변경
  • 모든 프로퍼티에 getter와 setter를 추가

언어와 IDE 설계자들은 getter와 setter를 이용해서 private 프로퍼티를 감싸는 방식을 권장합니다.

getter와 setter의 내부 구현과 무관하게 이들은 데이터일 뿐입니다. 다시 말해서 행동이 아닌 데이터를 표현할 뿐입니다.

접두사에 관한 모든 것

getter/setter 안티 패턴에서 두 접두사인 get과 set이라는 사실이 중요합니다. 그저 우리가 어떤 데이터를 객체 안에 넣어주거나 다시 꺼내주기를 원할 뿐이다.

class Cash {
    private final int value;
    public int dollars() {
        return this.value;
    }
}
class Cash {
    private final int value;
    public int getDollars() {
        return this.value;
    }
}
  • getDollars() 는 데이터 중에 dollars 를 찾은 후 반환하세요 라고 이야기하는 것이고, dollars() 는 얼마나 많은 달러가 필요한가요? 라고 묻는 것이다.
  • dollars() 는 객체를 데이터의 저장소로 취급하지 않고, 객체를 존중한다.
  • dollars() 는 데이터를 노출하지 않지만, getDollars() 는 데이터를 노출한다.

정리

  • 객체지향적이고 선언형 스타일을 유지하기 위해서는, 데이터를 객체 안에 감추고 절대로 외부에 노출해서는 안된다. 정확하게 무엇을 캡슐화하고 있고, 자료구조가 얼마나 복잡한 지는 오직 객체만이 알고 있어야 합니다.
  • getter와 setter의 내부 구현과 무관하게 이들은 데이터일 뿐이다. 다시 말해서 행동이 아닌 데이터를 표현할 뿐이다.
  • getter와 setter가 OOP에서 끔직한 안티 패턴이라는 것이다. 메서드의 이름을 절대 이런 방식으로 지어서는 안된다.

관련해서 생각해볼 내용

반응형