[Clean Code] Chapter 6. 객체와 자료 구조

joyful·2024년 8월 10일
0

개발서적

목록 보기
6/9
post-custom-banner

들어가기 앞서

이 글은 개발자 필독서인 클린 코드를 읽으며 습득한 내용을 정리한 글입니다. 모든 출처는 해당 저서에 있습니다.


💡 변수를 private으로 정의하는 이유

변수에 대한 의존성을 줄이고 변수 타입이나 구현의 변경을 쉽게하기 위해서



1. 자료 추상화

자료는 추상적인 개념으로 표현하는 편이 낫다. 단, 인터페이스나 조회/설정 함수만으로 추상화할 수 없다.

  • 변수를 private으로 선언하더라도 각 값마다 조회(get) 함수와 설정(set) 함수를 제공한다면 구현을 외부로 노출하는 셈이다.
  • 변수 사이에 함수라는 계층을 넣는다고 구현이 감춰지지 않는다. 구현을 감추려면 추상화가 필요하다.
    • 추상 인터페이스를 제공해 사용자가 구현을 모른 채 자료의 핵심을 조작할 수 있어야한다.

💻 구체적인 클래스

public class Point {
	public double x;
    public double y;
}
public interface Vehicle {
	double getFuelTankCapacityInGallons();
    double getGallonsOfGasoline();
}

💻 추상적인 클래스

public interface Point {
	double getX();
    double getY();
    void setCartesian(double x, double y);
    double getR();
    double getTheta();
    void setPolar(double r, double theta);
}
public interface Vehicle {
	double getPercentFuelRemaining();
}



2. 자료/객체 비대칭

  • 객체는 추상화를 통하여 자료는 숨기고, 자료를 다루는 함수만 공개한다.
  • 자료 구조는 자료를 공개하며 별다른 함수는 제공하지 않는다.

✅ 절차적 코드 VS 객체 지향 코드

절차적 코드객체 지향 코드
데이터 구성자료 구조객체
장점기존 자료 구조를 변경하지 않고 새로운 함수를 추가하기 쉬움기존 함수를 변경하지 않고 새로운 클래스를 추가하기 쉬움
단점새로운 자료 구조를 추가하려면 기존의 모든 함수를 수정해야 함새로운 함수를 추가하려면 기존의 모든 클래스를 수정해야 함
적합한 경우새로운 함수(기능)가 자주 추가되어야 하는 경우새로운 자료 타입(데이터 구조)이 자주 추가되어야 하는 경우
  • 어느 한 쪽에 치우지지 말고, 상황에 따라 유연하게 사용할 줄 알아야 한다.



3. 디미터 법칙

모듈은 자신이 조작하는 객체의 속사정을 몰라야 한다.

  • 객체는 자료를 숨기고 함수를 공개한다. 즉, 조회 함수로 내부 구조를 공개하면 안 된다.

  • 메소드 호출이 허용되는 객체

    종류
    클래스 C
    f가 생성한 객체
    f 인수로 넘어온 객체
    C 인스턴스 변수에 저장된 객체
    • 단, 위 객체에서 허용된 메소드가 반환하는 객체의 메소드호출해서는 안 된다.

3.1 기차 충돌(train wreck)

😈 개선 전

final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();
  • 여러 대의 객차가 한 줄로 이어진 기차처럼 보인다 하여 기차 충돌 코드라고 부른다.
  • 일반적으로 조잡하다 여겨지는 방식이므로 피하도록 한다.

😇 개선 후

Options opts = ctxt.getOptions();
File scratchDir = opts.getScratchDir();
final String outputDir = scratchDir.getAbsolutePath();
  • 위 코드를 사용하는 함수는 많은 객체를 탐색할 수 있으나, 디미터 법칙을 위반하는지 여부는 ctxt, Options, ScratchDir이 객체인지, 자료 구조인지에 따라 달라진다.

    자료 구조객체
    위반 여부OX
    이유내부 구조를 숨겨야 하므로내부 구조를 노출하므로
  • 다만, 조회 함수 사용으로 인한 혼란을 초래하는 것을 막기 위해 다음과 같은 소스 코드로 수정할 것을 권한다.

    final String outputDir = ctxt.options.scratchDir.absolutePath;
    • 위와 같이 수정함으로써 디미터 법칙 위반 여부를 따질 필요가 없어지게 된다.

3.2 잡종 구조

  • 무조건 자료 구조는 public 변수만, 객체는 private 변수와 public 함수를 포함한다면 명쾌해질 것이다.
  • 그러나 프레임워크와 표준으로 인해 절반은 객체, 절반은 자료 구조인 잡종 구조가 탄생한다.
  • 잡종 구조에는 중요 기능 수행 함수나 public 변수, public 조회/설정 함수 등이 있다.
  • 잡종 구조는 새로운 함수/자료 구조를 추가하기 어렵고, 객체 지향 코드과 절차적 코드의 단점만 모아놓은 구조이므로 되도록 피하도록 한다.

3.3 구조체 감추기

내부 구조를 드러내지 않고, 모듈에서 함수가 자신이 몰라야 하는 여러 객체를 탐색할 필요가 없도록 소스 코드를 작성하도록 한다.

😈 나쁜 예시 1

ctxt.getAbsolutePathOfScratchDirectoryOption();
  • ctxt 객체에 공개해야 하는 메소드가 많아짐

😈 나쁜 예시 2

ctx.getScratchDirectoryOption().getAbsolutePath();
  • getScratchDirectoryOption()이 자료 구조를 반환한다고 가정

😈 나쁜 예시 3

String outFile = outputDir + "/" + className.replace('.', '/') + ".class";
FileOutputStream fout = new FileOutputStream(outFile);
BufferedOutputStream bos = new BufferedOutputStream(fout);
  • 추상화 수준을 뒤섞어 놓음

😇 좋은 예시

BufferedOutputStream bos = ctxt.createScratchFileStream(classFileName);



4. 자료 전달 객체

✅ 자료 전달 객체(Data Transfer Object, DTO)

  • 자료 구조체의 전형적인 형태로, 공개 변수만 있고 함수가 없는 클래스
  • 데이터베이스와 통신하거나 소켓에서 받은 메시지의 구문을 분석할 때 유용
  • 데이터베이스에 저장된 가공되지 않은 정보를 응용 프로그램 코드에서 사용할 객체로 변환하는 일련의 단계에서 가장 처음으로 사용하는 구조체

✅ 빈(bean)

  • private 변수를 조회/설정 함수로 조작
    public class Address {
    	private String street;
      	private String city;
        private String state;
        private String zip;
        
        public Address(String street, String city, String state, String zip) {
        	this.street = street;
          	this.city = city;
          	this.state = state;
          	this.zip = zip;
        }
        
        public String getStreet() {
        	return street;
        }
        
        public String getCity() {
        	return city;
        }
        
        public String getState() {
        	return state;
        }
        
        public String getZip() {
        	return zip;
        }
    }

4.1 활성 레코드

  • DTO의 특수한 형태
    • public 변수가 있거나 private 변수에 조회/설정 함수가 있는 자료구조
    • save나 find와 같은 탐색 함수도 제공
    • 데이터베이스 테이블이나 다른 소스에서 자료를 직접 변환한 결과
  • 자료 구조로 취급하며, 비즈니스 규칙을 담으면서 내부 자료를 숨기는 객체는 따로 생성하도록 한다.

📖 참고

  • 로버트 C. 마틴, 『Clean Code 클린 코드 애자일 소프트웨어 장인 정신』, 박재호·이해영 옮김, 케이앤피북스(2010), p147-158.
profile
기쁘게 코딩하고 싶은 백엔드 개발자
post-custom-banner

0개의 댓글