쾌락코딩

클린코드_객체와 자료 구조

|

클래스의 변수들은 왜 대부분 비공개로 정의할까? 그것은 남들이 변수에 의존하지 않게 만들고 싶어서다. 그렇다면 어째서 수많은 프로그래머가 getter와 setter함수를 당연하게 public으로 비공개 변수를 외부에 노출할까?

자료 전달 객체

사실 private 변수에 대해 getter와 setter를 제공해야 하는 상황은 명확하다. 그 클래스가 자료구조(자료 전달 객체 - DTO(Data Transfer Ojbect))이면 그렇게 하는 것이다(단순한 자료 구조에도 getter와 setter를 정의하라는 표준이 존재한다). DTO란 전형적인 공개 변수만 있고 함수가 없는 클래스다. 예를 들어 데이터베이스와 통신하거나 소켓에서 받은 메시지의 구문을 분석할 때 유용한 클래스들이다.

좀 더 일반적인 형태는 ‘빈(bean)’ 구조이다. 빈은 private 변수를 조회/설정 함수로 조작한다. 예시 코드는 아래와 같다.

public class Address {
    private String street;
    private String streetExtra;
    private String city;

    public Address(String street, String streetExtra, String city) {
        this.street = street;
        this.streetExtra = streetExtra;
        this.city = city;
    }

    public String getStreet() {
        return street;
    }

    public String getStreetExtra() {
        return streetExtra;
    }

    ....
}

활성레코드

활성레코드 라 불리는 것은 DTO의 특수한 형태다. public 변수가 있거나 비공개 변수에 getter/setter 함수가 있는 자료구조지만, 대게 save나 find와 같은 탐색 함수도 제공한다.

불행히도 활성 레코드에 비즈니스 규칙 메서드를 추가해 이런 자료 구조를 객체로 취급하는 개발자가 흔하다. 하지만 이는 바람직하지 않다. 그러면 자료 구조도 아니고 객체도 아닌 잡종 구조가 나오기 때문이다. 활성 레코드는 자료 구조로 취급하라.

자료 추상화

객체지향은 구현을 외부로 노출하지 않아야 좋은 코드가 된다.

public class Point {
    private double x;
    private double y;

    ...

    public double getX() {
        return x;
    }

    public double getY() {
        return y;
    }
}

위의 코드처럼 변수를 private으로 선언하더라도 각 값마다 getter와 setter를 제공한다면 구현을 외부로 노출하는 셈이다. 꼭 Point 객체를 생성해서 접근 해야 하지만 결과적으로 구현이 노출되는 것은 같다.

위의 예시처럼 변수 사이에 함수라는 계층을 넣는다고 구현이 저절로 감춰지진 않는다. 즉, DTO에 getter, setter를 추가해서 다룬다고 객체지향 패러다임의 객체가 되진 않는다. 객체란, 내부 구현을 감추고 캡슐화, 추상화를 고려해 기능을 제공하는 것이기 때문이다. 따라서, 추상 인터페이스(꼭 자바 문법의 interface가 아니라 추상적인 메서드가 될 수 도 있다)를 제공해 사용자가 구현을 모른 채 자료의 핵심을 조작할 수 있어야 진정한 의미의 객체(또는 클래스)다.

개발자는 객체가 포함하는 자료를 표현할 가장 좋은 방법을 심각하게 고민해야 한다. 아무 생각 없이 조회/설정 함수를 추가하는 방법이 가장 나쁘다.

잡종 구조

아무 생각 없이 조회/설정 함수를 추가하게 되면 잡종 구조가 나오게 된다. 절반은 객체, 절반은 자료 구조인 것이다. 잡종 구조는 중요한 기능을 수행하는 함수도 있고, 공개 변수나 공개 조회/설정 함수도 있다. 공개 조회/설정 함수는 비공개(private) 변수를 그대로 노출한다. 덕탠에 다른 함수가 절차적인 프로그래밍의 자료 구조 접근 방식처럼 비공개 변수를 사용하고픈 유혹에 빠쥐기 쉽다.

이런 잡종 구조는 새로운 함수는 물론이고 새로운 자료 구조도 추가하기 어렵다. 그러므로 잡종 구조는 되도록 피하는 편이 좋다. 프로그래머가 함수나 타입을 보호할지 공개할지 확신하지 못해 어중간하게 내놓은 설계에 불과하다.

###결론 단순히 자료구로라고 판단된다면 getter, setter 정도(상황에 따라 활성 레코드로)만 있는게 좋고, 객체라면 getter, setter 없이 추상적인 함수(기능)을 제공하자.

Comments