coding8282
1k
2016-12-02 14:44:18 작성 2016-12-02 14:45:23 수정됨
7
2179

Why getter and setter methods are evil


예전 한 4년 전쯤? 학생 때 getter,setter가 나쁜 패턴이라는 글을 본 기억이 있었는데요 근래에 갑자기 그 컬럼이 생각이 나서 찾아보니 많은 언급이 있네요.


http://www.javaworld.com/article/2073723/core-java/why-getter-and-setter-methods-are-evil.html


그 이래로 setter/getter는 그냥 자연스럽게 사용했었는데요, 이게 요새들어서는 어떻게 평가되고 있는지 궁금합니다. 이쪽에서 오래 일하신 분들+한국 실정에 따라서 견해가 많이 다를 것 같네요.

3
0
  • 답변 7

  • 유글레나
    527
    2016-12-02 15:21:24

    DTO의 경우에는 각 레이어간 데이터를 전달하는게 주 목적이기 때문에 getter/setter가 필요합니다. 하지만 객체에서는 좋지못한 방식이라고 봅니다.

    객체지향에서 객체란 내부의 속성은 최대한 숨기며 외부에는 최소한의 인터페이스(메서드)만을 노출하는것이 좋습니다. 이러한 객체지향적인 패러다임으로 보았을 경우 특히나 setter는 내부의 속성을 외부에서 수정할 수 있는 여지를 만들어줄 수 있기 때문이지요.

    다만 한국형 개발(mybatis를 이용)에서는 로직이 SQL로 종속되는 경우가 많아지며 객체가 아닌 단순한 데이터의 전달용도인 DTO이상으로 활용이 되지 못하는것 같아요.


    1
  • 하늬바람
    483
    2016-12-02 15:40:11

    굉장히 유명한 분들의 2013년경 관련 논쟁도 올려봅니다.

    이 주제로 이곳에서도 뜨거운 논쟁이 불붙었더랬죠.

    http://itmemo.tistory.com/105

    수년전만 하더라도 이 논쟁이 매우 중요하다고 생각하다가 근자에 들어 생각이 바뀌어 "그다지 무게감이 있는 논쟁은 아니다." 쪽으로 기울어 가고 있습니다.

    1
  • Rel
    1k
    2016-12-02 16:41:09

    저도 개인적으로 궁금했었어요! 기본을 몰라 그냥 단순하게 데이터 꺼내가는 것 뿐인데 왜 public 변수 말고 getter/setter 쓰는 건지, 결과적으로 보면 같은 게 아닌가? 이런 생각만 했었는데.. 좋은 글들 많이 주셔서 감사합니다 :) 

    (아래 내용은 하늬바람님께서 첨부해 주셨던 글과 조금 중복되는 내용이 있습니다..)

    부끄럽지만 진짜 public 속성과 getter/setter메소드 이용하는 방식이랑 차이가 큰가요? 저는 원본 값을 그대로 저장하고 그 값을 계산해서 출력해야 하는 경우(이런 경우는 getter 메소드라고 하진 않죠..?)나, 특정 형식으로 출력해야 하는 경우(예를 들어 [n+"원"])에는 getter/setter 메소드를 사용해야 한다고 생각하지만..

    그 외, 단순한 참조나 대입 같은 경우는 public 속성을 사용하는 것과 getter/setter 메소드를 사용하는 것에 대한 차이가 뭔지 모르겠어요.

    변수 A를 '과자'에 비유한다고 하고, 그 변수를 가져와서 작업한다는 걸 '먹는다'는 행동에 비유하자면..
    public 속성 -> 내가 직접 그 과자를 먹는다.
    getter/setter -> 내가 누군가한테 그 과자를 달라고 해서 그 과자를 먹는다.
    이렇게 되는 것 같은데.. (저렴한 머리로 저렴한 비유...)

    음.. 부족한 제 머리로는 저 두개 차이가 뭔지 잘 모르겠네요.. :( 

    1
  • GAN
    1k
    2016-12-02 17:02:54 작성 2016-12-02 17:03:24 수정됨

    멤버 변수를 public 으로 공개하는 건 나중에 해당 클래스의 내부 구현을 변경하기 힘들게 만듭니다.

    내부에서 해당 소스를 변경할 수 있는 사람들만 사용하는 클래스일 경우 큰 문제는 없을 수 있지만
    해당 클래스를 수정할 수 없는 사람(외부)에게 공개하는 순간 해당 public 변수 및 메소드는 버전을 올릴 때마다 계속 유지를 해줘야 합니다.

    만약 외부에 공개한 클래스의 public 변수나 메소드를 버전업을 하면서 삭제를 하거나 변경을 할 경우 해당 클래스를 사용하고 있는 다른 소스가 동작을 안 할 수도 있어서 버그 패치나 성능 개선 시에도 새 버전을 가져다 쓰기 힘들게 됩니다.(특별한 이유가 없으면 라이브러리 버전을 잘 안 올리려고 하는 이유이기도 합니다.)

    @Deprecated 를 지정해서 해당 변수, 메소드 사용을 자제할 것을 알리고 차후에 없애는 경우도 있고요.

    관련된 예로 최근 안드로이드의 Configuration 클래스를 사용할 일이 있었는데 locale 변수를 public 으로 지정했다가 버전이 올라가면서 getLocale() 메소드와 setLocales(LocaleList) 메소드가 생겼더군요.


    Java 는 아니지만 Effective C++ 에서는 public 만이 아닌 protected 도 사실상 보호받지 못 한다는 글이 있습니다.

    2
  • GAN
    1k
    2016-12-02 17:15:52

    getter/setter 와 관련해서는 최근(?) 나온 언어들은 Property 를 지원해서 public 변수처럼 사용하다가 getter setter 처럼 사용할 일이 생기면 Property 지정을 해서 사용하는 경우도 있습니다.

    Groovy 로 예로 들면

    import groovy.transform.*
    
    @TupleConstructor
    @ToString
    class Item {
        int id
        String name
    }
    
    def item = new Item(1, 'item1')
    println item
    
    item.id = 2
    item.name = 'item2'
    println item

    이런 코드에 setter를 추가하면

    class Item {
        int id
        String name
    
        public setId(int id) {
            this.id = id + 10
        }
    }

    대입 연산자를 사용하더라도 setter를 사용하게 됩니다.

    1
  • 유글레나
    527
    2016-12-02 17:18:12

    @하늬바람

    해당 논쟁이 어떻게 끝났는지는 잘 모르겠지만 저는 객체지향의 중요도는 결코 낮지 않다고 생각합니다. 객체화한다 즉 추상화한다는 것은 복잡도를 낮추고 읽을수 있게 만들수 있도록 만들어줍니다.

    ValueObject는 하나의 대상을 묶어 큰 그림으로 바라보도록 만들어줄 수 있습니다. 링크해주신 글의 VO는 DTO와 같은 의미로 사용하고 있는것 같은데, 둘의 관계와 용도는 결코 동일하지 않습니다.
    ValueObject에 관련된 내용은 http://martinfowler.com/bliki/ValueObject.html 여기 글 참고 부탁드리겠습니다.

    프로그램은 기간이 지나갈수록 복잡도가 높아지며 이를 최대한 감출 수 있는 방법은 객체지향이라고 봅니다. 논쟁이 아니라 당연히 받아들여진걸로 저는 생각합니다.


    @Rel

    네 정확하게 잘 집어주신것 같습니다. 말씀하신대로 단순한 getter/setter로 이루어진 모델은 외부의 로직을 통해서 데이터를 수정할 수 있게됩니다. 문제는 이런 객체는 참조를 통해서 전파될 수 있으며 로직이 복잡해지는 경우에 엉뚱한곳에서 변경될 수 있는 여지를 가질 수 있게 됩니다. 어디서 변경되는지 모르기에 디버깅도 쉽지 않으며 무엇보다도 객체들의 책임이 분산되는 결과를 낳을 수 있게 됩니다.

    그렇기 때문에 데이터의 변경을 최대한 막을수 있도록 setter를 만들지 않는것이 좋습니다. 대신 명쾌한 메서드만을 노출하는것이 좋습니다.



    1
  • coding8282
    1k
    2016-12-02 21:24:58 작성 2016-12-02 21:25:43 수정됨

    @하늬바람 

    이것은 vo vs map 논쟁인가요? 오키에더 관련 글이 많이 있어서 제가 쭉 시간내서 본 적이 있는데요, 흥미로운점은 객체지향을 주장하시는 분들은 vo를 선택하였고 map의 편의성 및 유연함은 한국에서 객체지향적인 설계없이 그저 찍어내듯 코딩하는 나쁜 관행 때문에 나오는 구조적인 문제로 결론 난 것 같아요. 저는 그래서 제대로된 설계라면 맵을 사용할 여지가 없는 것으로 판단하고 있습니다

    1
  • 로그인을 하시면 답변을 등록할 수 있습니다.